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

ctypes: การเรียกใช้ไลบรารี C จาก Python

โหลดไลบรารีที่ใช้ร่วมกันและเรียกฟังก์ชัน C ด้วย ctypes

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

ctypes คืออะไร

ctypes เป็นโมดูลในไลบรารีมาตรฐานสำหรับโหลดไลบรารี C ที่ใช้ร่วมกันและเรียกใช้ฟังก์ชันของไลบรารีเหล่านั้นจาก Python โดยไม่ต้องคอมไพล์

import ctypes

# Load the C standard library
libc = ctypes.CDLL("libc.so.6")   # Linux
# libc = ctypes.CDLL("libSystem.dylib")  # macOS

libc.puts(b"Hello from C!")

การโหลดไลบรารี

ใช้ ctypes.CDLL สำหรับรูปแบบการเรียก cdecl (ไลบรารี C ส่วนใหญ่) และใช้ WinDLL สำหรับ API ของ Windows ที่ใช้ stdcall

import ctypes

# Platform-independent approach:
import ctypes.util
libm_name = ctypes.util.find_library("m")
libm = ctypes.CDLL(libm_name)

result = libm.sqrt
result.restype = ctypes.c_double
result.argtypes = [ctypes.c_double]
print(result(2.0))   # 1.4142...

ชนิดข้อมูลของ C

จับคู่ชนิดข้อมูลของ Python กับชนิดข้อมูลของ C โดยใช้คลาสของ ctypes ได้แก่ c_int, c_double, c_char_p, c_void_p เป็นต้น

import ctypes

x = ctypes.c_int(42)
print(x.value)   # 42

d = ctypes.c_double(3.14)
print(d.value)   # 3.14

s = ctypes.c_char_p(b"hello")
print(s.value)   # b"hello"

การกำหนด argtypes และ restype

ประกาศ argtypes (ชนิดพารามิเตอร์) และ restype (ชนิดค่าที่ส่งคืน) เสมอ เพื่อหลีกเลี่ยงข้อขัดข้องที่ไม่แสดงข้อความจากชนิดข้อมูลไม่ตรงกัน

import ctypes, ctypes.util

libm = ctypes.CDLL(ctypes.util.find_library("m"))

libm.pow.argtypes = [ctypes.c_double, ctypes.c_double]
libm.pow.restype  = ctypes.c_double

print(libm.pow(2.0, 10.0))   # 1024.0

การส่งพอยน์เตอร์

ใช้ ctypes.byref(var) หรือ ctypes.pointer(var) เพื่อส่งพอยน์เตอร์ไปยังตัวแปรของ C

import ctypes

libc = ctypes.CDLL(None)   # None = current process

value = ctypes.c_int(0)
# Passing pointer to C function:
# libc.some_func(ctypes.byref(value))
print(value.value)

โครงสร้าง

กำหนดโครงสร้าง C โดยสืบทอดคลาสจาก ctypes.Structure และระบุรายการ _fields_

import ctypes

class Point(ctypes.Structure):
    _fields_ = [
        ("x", ctypes.c_double),
        ("y", ctypes.c_double),
    ]

p = Point(1.0, 2.0)
print(p.x, p.y)   # 1.0 2.0

อาร์เรย์

สร้างอาร์เรย์ C ด้วย TypeClass * N

import ctypes

IntArray5 = ctypes.c_int * 5
arr = IntArray5(10, 20, 30, 40, 50)
for v in arr:
    print(v, end=" ")   # 10 20 30 40 50

ฟังก์ชันเรียกกลับ (พอยน์เตอร์ฟังก์ชัน)

ใช้ ctypes.CFUNCTYPE เพื่อสร้างฟังก์ชัน Python ที่ C เรียกใช้ได้ แล้วส่งฟังก์ชันนั้นเป็นฟังก์ชันเรียกกลับ

import ctypes

CompareFunc = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)

def my_compare(a, b):
    return a - b

c_compare = CompareFunc(my_compare)
# Pass c_compare to a C function expecting a comparator

การโหลด DLL ของ Windows

บน Windows ให้ใช้ ctypes.WinDLL สำหรับ DLL ที่ใช้รูปแบบการเรียก stdcall เช่น Windows API

import ctypes   # Windows only

kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
kernel32.GetTickCount.restype = ctypes.c_ulong
print(kernel32.GetTickCount())

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

ตรวจสอบ ctypes.get_last_error() (บน Windows) หรือใช้ try/except ระดับ Python สำหรับข้อผิดพลาดที่ส่งคืนมาเป็นค่าพิเศษ

import ctypes

# Many C functions return -1 or NULL on error:
result = some_c_function()
if result == -1:
    raise OSError("C function failed")

# For errno on POSIX:
import os
if result < 0:
    raise OSError(os.strerror(ctypes.get_errno()))

ตัวอย่างเชิงปฏิบัติ: SHA-256 ด้วย OpenSSL

เรียกใช้ SHA256 ของ OpenSSL โดยตรงผ่าน ctypes ได้โดยไม่ต้องใช้ไลบรารีเชื่อมโยงกับ Python

import ctypes, ctypes.util

libcrypto = ctypes.CDLL(ctypes.util.find_library("crypto"))

SHA256 = libcrypto.SHA256
SHA256.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_char_p]
SHA256.restype  = ctypes.c_char_p

buf = ctypes.create_string_buffer(32)
SHA256(b"hello", 5, buf)
print(buf.raw.hex())

ตรวจสอบอย่างรวดเร็ว

เหตุใดจึงควรกำหนด argtypes และ restype ให้กับฟังก์ชัน ctypes เสมอ

สรุป

ctypes โหลดไลบรารี C ที่ใช้ร่วมกันได้โดยไม่ต้องคอมไพล์ ประกาศ argtypes และ restype ให้กับทุกฟังก์ชัน ใช้ Structure สำหรับโครงสร้าง C ใช้ TypeClass * N สำหรับอาร์เรย์ และใช้ CFUNCTYPE สำหรับฟังก์ชันเรียกกลับ

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

บทเรียน “ctypes: การเรียกใช้ไลบรารี C จาก Python” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ctypes: การเรียกใช้ไลบรารี C จาก Python”

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

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

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

บทเรียน “ctypes: การเรียกใช้ไลบรารี C จาก Python” ใช้เวลานานแค่ไหน

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

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

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

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

  1. เหตุผลที่ต้องใช้ส่วนขยาย C: กรณีใช้งานและข้อแลกเปลี่ยน
  2. ctypes: การเรียกใช้ไลบรารี C จาก Python
  3. cffi: อินเทอร์เฟซฟังก์ชันภายนอกของ C
  4. การเขียนโมดูลส่วนขยาย C ของ Python
← กลับไปที่ Python Academy