0Pricing
Lua Academy · บทเรียน

การเรียกฟังก์ชัน C ผ่าน FFI

เรียกใช้ฟังก์ชัน libc และไลบรารีที่ใช้ร่วมกันแบบกำหนดเองจาก Lua โดยแทบไม่มีค่าใช้จ่ายเพิ่มเติม

การเรียกฟังก์ชัน C ผ่าน FFI เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

การเรียกฟังก์ชัน C โดยตรง

เมื่อประกาศด้วย ffi.cdef แล้ว จะเรียกฟังก์ชัน C ได้เหมือนฟังก์ชัน Lua ทุกประการผ่านออบเจ็กต์ไลบรารี อาร์กิวเมนต์และค่าที่คืนกลับมาจะถูกแปลงโดยอัตโนมัติ

local ffi = require("ffi")
ffi.cdef[[ double sin(double x); ]]
local m = ffi.load("m")
print(m.sin(math.pi / 2))  -- 1.0

การแปลงชนิดข้อมูล

โดยค่าเริ่มต้น ตัวเลข Lua จะกลายเป็น double ของ C FFI จะแปลงเป็นชนิดพารามิเตอร์ C ที่ประกาศไว้โดยอัตโนมัติ ค่าบูลีนจะกลายเป็น 0/1 ส่วนสตริงจะกลายเป็น const char*

การเรียกใช้ printf

printf เป็นฟังก์ชัน C แบบรับอาร์กิวเมนต์ได้ไม่จำกัดจำนวน ให้เรียกผ่าน ffi.C.printf โดยส่งสตริงรูปแบบและอาร์กิวเมนต์

ffi.cdef[[ int printf(const char *fmt, ...); ]]
ffi.C.printf("Sum: %d\n", 42)

การจัดการค่าที่คืนกลับมา

ค่าที่คืนกลับจาก C จะถูกแปลงเป็นชนิดข้อมูล Lua โดยอัตโนมัติ จำนวนเต็มจะกลายเป็นตัวเลข Lua ส่วน char* จะกลายเป็น lightuserdata (ใช้ ffi.string เพื่อแปลง)

ffi.cdef[[ char *getenv(const char *name); ]]
local ptr = ffi.C.getenv("HOME")
if ptr ~= nil then
  print(ffi.string(ptr))
end

ffi.string

ffi.string(ptr, len) แปลงพอยน์เตอร์ char* เป็นสตริง Lua หากไม่ระบุ len ฟังก์ชันจะอ่านจนพบไบต์ว่าง

การจัดการข้อผิดพลาด

ฟังก์ชัน C จะคืนรหัสข้อผิดพลาดหรือตั้งค่า errno ตรวจสอบค่าที่คืนกลับมาอย่างชัดเจน เข้าถึง errno ผ่าน ffi.errno()

ffi.cdef[[ int open(const char *path, int flags); ]]
local fd = ffi.C.open("missing.txt", 0)
if fd < 0 then
  print("Error:", ffi.errno())
end

อาร์กิวเมนต์ชนิดโครงสร้าง

ส่งโครงสร้าง C เป็นค่าโดยตรงหรือเป็นพอยน์เตอร์ได้ สร้างโครงสร้างด้วย ffi.new

ffi.cdef[[
  typedef struct { int x, y; } Point;
  void printPoint(Point p);
]]
local p = ffi.new("Point", {x=3, y=4})
lib.printPoint(p)

อาร์กิวเมนต์ชนิดพอยน์เตอร์

ส่งพอยน์เตอร์ผลลัพธ์ให้ฟังก์ชันที่คืนค่าหลายค่าผ่านพารามิเตอร์พอยน์เตอร์

ffi.cdef[[
  void minmax(double *arr, int n, double *min, double *max);
]]
local arr = ffi.new("double[5]", {5,2,8,1,9})
local mn, mx = ffi.new("double[1]"), ffi.new("double[1]")
lib.minmax(arr, 5, mn, mx)
print(mn[0], mx[0])

ประสิทธิภาพการเรียกใช้ FFI

การเรียกฟังก์ชัน C ผ่าน FFI มีค่าใช้จ่ายเกือบเป็นศูนย์ จึงเร็วกว่าการเรียกจาก Lua ไปยัง C ผ่าน API แบบดั้งเดิมมาก และ JIT มักแทรกการเรียกใช้ทั้งหมดไว้ในโค้ดได้

ฟังก์ชันแบบรับอาร์กิวเมนต์ได้ไม่จำกัดจำนวน

ฟังก์ชัน C แบบรับอาร์กิวเมนต์ได้ไม่จำกัดจำนวน (...) ต้องเรียกด้วยชนิดข้อมูลที่ถูกต้อง หากจำเป็น ให้ส่งการแปลงชนิดข้อมูลอย่างชัดเจนเพื่อหลีกเลี่ยงความกำกวม

ffi.C.printf("%d %f\n", ffi.cast("int", 42), ffi.cast("double", 3.14))

แนวทางปฏิบัติด้านความปลอดภัย

ตรวจสอบค่าพอยน์เตอร์ที่คืนกลับมาเสมอว่าไม่ใช่ NULL อย่าส่งพอยน์เตอร์ที่ถูกคืนหน่วยความจำแล้วหรืออยู่นอกขอบเขต ใช้ ffi.gc เพื่อผูกฟังก์ชันเก็บกวาดกับการจัดสรรหน่วยความจำของ C

คำถามเกี่ยวกับการเรียกใช้ FFI

FFI จัดการแปลงสตริง Lua เป็น const char* ของ C อย่างไร

สรุป: การเรียกใช้ C ผ่าน FFI

เรียกฟังก์ชัน C ผ่านออบเจ็กต์ไลบรารีเช่นเดียวกับฟังก์ชัน Lua FFI จัดการแปลงชนิดข้อมูลให้ ใช้ ffi.string สำหรับค่าประเภท char* ที่คืนกลับมา ใช้ ffi.errno() สำหรับข้อผิดพลาด และใช้ ffi.new สำหรับอาร์กิวเมนต์ชนิดโครงสร้างหรืออาร์เรย์

คำถามที่พบบ่อย

บทเรียน “การเรียกฟังก์ชัน C ผ่าน FFI” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเรียกฟังก์ชัน C ผ่าน FFI” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเรียกฟังก์ชัน C ผ่าน FFI”

เรียกใช้ฟังก์ชัน libc และไลบรารีที่ใช้ร่วมกันแบบกำหนดเองจาก Lua โดยแทบไม่มีค่าใช้จ่ายเพิ่มเติม คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การเรียกฟังก์ชัน C ผ่าน FFI” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม

ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐาน FFI: ffi.cdef และ ffi.load
  2. การเรียกฟังก์ชัน C ผ่าน FFI
  3. พอยน์เตอร์ โครงสร้าง และอาร์เรย์ใน FFI
  4. ฟังก์ชันเรียกกลับ: การส่งฟังก์ชัน Lua ให้ C
← กลับไปที่ Lua Academy