cffi: อินเทอร์เฟซฟังก์ชันภายนอกของ C
ใช้ cffi เพื่อทำงานร่วมกับ C แบบเป็นธรรมชาติสำหรับ Python มากขึ้น พร้อมการประกาศ C แบบแทรกในโค้ด
cffi: อินเทอร์เฟซฟังก์ชันภายนอกของ C เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
cffi คืออะไร
cffi (อินเทอร์เฟซฟังก์ชันภายนอกของ C) ช่วยให้คุณเรียกใช้โค้ด C จาก Python โดยใช้คำประกาศของ C แทนคลาสของ ctypes วิธีนี้มีรูปแบบเป็น Python มากกว่าและมักปลอดภัยกว่า
# pip install cffi
from cffi import FFI
ffi = FFI()
ffi.cdef("double sqrt(double x);")
libm = ffi.dlopen(None) # current process
print(libm.sqrt(2.0)) # 1.4142...โหมด ABI กับโหมด API
ffi.dlopen() เป็นโหมด ABI ซึ่งเรียกใช้ไลบรารีที่ใช้ร่วมกันที่มีอยู่แล้วขณะทำงาน ส่วนโหมด API จะคอมไพล์ตัวห่อหุ้ม C และทำงานได้เร็วกว่าและมีความทนทานมากกว่า
from cffi import FFI
ffi = FFI()
# ABI mode (no compile step):
ffi.cdef("int abs(int x);")
libc = ffi.dlopen("libc.so.6") # Linux
print(libc.abs(-42)) # 42การประกาศด้วย cdef
ใช้ ffi.cdef() เพื่อประกาศลายเซ็นฟังก์ชัน โครงสร้าง และ typedef ของ C ที่ต้องการใช้จาก Python
from cffi import FFI
ffi = FFI()
ffi.cdef("""
typedef struct {
double x;
double y;
} Point;
double distance(Point a, Point b);
""")
# lib = ffi.dlopen("mylib.so")การสร้างโครงสร้าง C
ใช้ ffi.new() เพื่อจัดสรรโครงสร้าง C และกำหนดฟิลด์ของโครงสร้างจาก Python
from cffi import FFI
ffi = FFI()
ffi.cdef("typedef struct { int x; int y; } Vec2;")
lib = ffi.dlopen(None)
v = ffi.new("Vec2 *")
v.x = 3
v.y = 4
print(v.x, v.y) # 3 4สตริงและบัฟเฟอร์
ใช้ ffi.new("char[]", n) สำหรับบัฟเฟอร์ที่แก้ไขได้ และใช้ ffi.string(ptr) เพื่อแปลงพอยน์เตอร์สตริง C เป็นไบต์ของ Python
from cffi import FFI
ffi = FFI()
buf = ffi.new("char[]", b"hello world")
print(ffi.string(buf)) # b"hello world"
# Mutable buffer for output:
out = ffi.new("char[128]")
# c_func(out, 128) # fill the buffer
# result = ffi.string(out).decode()โหมด API พร้อมการตรวจสอบ
โหมด API จะคอมไพล์โมดูลตัวห่อหุ้ม C ขนาดเล็กเพื่อความปลอดภัยของชนิดข้อมูลและประสิทธิภาพที่ดียิ่งขึ้น ใช้ ffi.set_source() และสร้างโมดูลแบบออฟไลน์
from cffi import FFI
ffi = FFI()
ffi.cdef("int add(int a, int b);")
ffi.set_source("_mylib",
"""
int add(int a, int b) { return a + b; }
"""
)
# Build: python build_mylib.py
# from _mylib import ffi, lib
# print(lib.add(3, 4)) # 7ฟังก์ชันเรียกกลับจาก C ไปยัง Python
ใช้ ffi.callback() เพื่อห่อฟังก์ชัน Python ให้เป็นพอยน์เตอร์ฟังก์ชัน C ซึ่งสามารถส่งให้ไลบรารี C ได้
from cffi import FFI
ffi = FFI()
ffi.cdef("typedef int (*compare_fn)(int, int);")
@ffi.callback("int(int, int)")
def compare(a, b):
return a - b
# pass compare to a C sort functionการจัดการหน่วยความจำ
อ็อบเจ็กต์ที่จัดสรรด้วย ffi.new() จะอยู่ภายใต้การจัดการของ Python และถูกคืนพื้นที่โดยอัตโนมัติ ใช้ ffi.gc(ptr, destructor) เพื่อผูกตัวคืนพื้นที่แบบกำหนดเอง
from cffi import FFI
ffi = FFI()
# ptr freed when Python GC collects it:
buf = ffi.new("int[10]")
buf[0] = 42
print(buf[0]) # 42
# Custom destructor:
# ptr = ffi.gc(lib.alloc(), lib.free)cffi กับ ctypes
cffi ใช้สตริงคำประกาศของ C ซึ่งเป็นธรรมชาติกว่าสำหรับนักพัฒนา C ขณะที่ ctypes ใช้คลาสของ Python โหมด API ของ cffi ทำงานได้เร็วกว่า ส่วน ctypes ไม่ต้องคอมไพล์
# ctypes approach:
import ctypes
libc = ctypes.CDLL("libc.so.6")
libc.abs.restype = ctypes.c_int
libc.abs.argtypes = [ctypes.c_int]
print(libc.abs(-5)) # 5
# cffi approach:
from cffi import FFI; ffi = FFI()
ffi.cdef("int abs(int);")
lib = ffi.dlopen(None)
print(lib.abs(-5)) # 5การใช้ cffi กับ NumPy
ส่งข้อมูลอาร์เรย์ NumPy ไปยัง C โดยตรงผ่าน cffi ด้วย ffi.cast() และพอยน์เตอร์ ctypes.data ของอาร์เรย์
import numpy as np
from cffi import FFI
ffi = FFI()
arr = np.array([1.0, 2.0, 3.0])
ptr = ffi.cast("double *", arr.ctypes.data)
# Now ptr can be passed to a C function expecting double*การจัดการข้อผิดพลาดด้วย cffi
โดยทั่วไปฟังก์ชัน C จะส่งสัญญาณข้อผิดพลาดผ่านค่าที่ส่งคืน ให้ตรวจสอบค่าที่ส่งคืนและใช้ ffi.errno สำหรับรหัสข้อผิดพลาดของ POSIX
import errno as errno_mod
from cffi import FFI
ffi = FFI()
ffi.cdef("int open(const char *path, int flags);")
lib = ffi.dlopen(None)
fd = lib.open(b"/nonexistent", 0)
if fd == -1:
err = ffi.errno
raise OSError(err, "open failed")ตรวจสอบอย่างรวดเร็ว
cffi ใช้วิธีใดในการประกาศลายเซ็นฟังก์ชัน C ที่ต้องการเรียกใช้
สรุป
cffi ใช้ ffi.cdef() เพื่อประกาศลายเซ็นของ C และใช้ ffi.dlopen() สำหรับการเรียกใช้ไลบรารีในโหมด ABI โหมด API จะคอมไพล์ตัวห่อหุ้มเพื่อประสิทธิภาพที่ดียิ่งขึ้น ใช้ ffi.new() สำหรับหน่วยความจำของ C และใช้ ffi.callback() สำหรับฟังก์ชันเรียกกลับจาก Python ไปยัง C
คำถามที่พบบ่อย
บทเรียน “cffi: อินเทอร์เฟซฟังก์ชันภายนอกของ C” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “cffi: อินเทอร์เฟซฟังก์ชันภายนอกของ C” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “cffi: อินเทอร์เฟซฟังก์ชันภายนอกของ C”
ใช้ cffi เพื่อทำงานร่วมกับ C แบบเป็นธรรมชาติสำหรับ Python มากขึ้น พร้อมการประกาศ C แบบแทรกในโค้ด คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “cffi: อินเทอร์เฟซฟังก์ชันภายนอกของ C” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม
ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เหตุผลที่ต้องใช้ส่วนขยาย C: กรณีใช้งานและข้อแลกเปลี่ยน
- ctypes: การเรียกใช้ไลบรารี C จาก Python
- cffi: อินเทอร์เฟซฟังก์ชันภายนอกของ C
- การเขียนโมดูลส่วนขยาย C ของ Python