0Pricing
Python Academy · درس

ctypes: استدعاء مكتبات C من Python

حمّل المكتبات المشتركة واستدعِ دوال C باستخدام ctypes

ctypes: استدعاء مكتبات C من Python درس مجاني في Python Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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 مع واجهات Windows API التي تستخدم 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» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Python Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Python Academy 4 دروس في المجموع.

ماذا ستتعلم في «ctypes: استدعاء مكتبات C من Python»؟

حمّل المكتبات المشتركة واستدعِ دوال C باستخدام ctypes تتمرن على Python Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Python Academy؟

لا تُشترط خبرة سابقة. Python Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «ctypes: استدعاء مكتبات C من Python»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Python Academy هذا؟

نعم. كل درس في Python Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. لماذا امتدادات C؟ حالات الاستخدام والمفاضلات
  2. ctypes: استدعاء مكتبات C من Python
  3. cffi: واجهة الدوال الأجنبية لـ C
  4. كتابة وحدة امتداد C لـ Python
← العودة إلى Python Academy