نواصل موضوع كيفية استدعاء C / C ++ من Python3 . الآن نستخدم مكتبات cffi و pybind11 . تمت مناقشة الطريقة من خلال ctypes في مقال سابق.
C
مكتبة اختبار لشرح العمل مع المتغيرات العالمية والهياكل والوظائف مع الوسائط من أنواع مختلفة.
test.h
typedef struct test_st_s test_st_t; extern int a; extern double b; extern char c; int func_ret_int(int val); double func_ret_double(double val); char *func_ret_str(char *val); char func_many_args(int val1, double val2, char val3, short val4); test_st_t *func_ret_struct(test_st_t *test_st); struct test_st_s { int val1; double val2; char val3; };
test.c
#include <stdio.h> #include <stdlib.h> #include "test.h" int a = 5; double b = 5.12345; char c = 'X'; int func_ret_int(int val) { printf("C get func_ret_int: %d\n", val); return val; } double func_ret_double(double val) { printf("C get func_ret_double: %f\n", val); return val; } char * func_ret_str(char *val) { printf("C get func_ret_str: %s\n", val); return val; } char func_many_args(int val1, double val2, char val3, short val4) { printf("C get func_many_args: int - %d, double - %f, char - %c, short - %d\n", val1, val2, val3, val4); return val3; } test_st_t * func_ret_struct(test_st_t *test_st) { if (test_st) { printf("C get test_st: val1 - %d, val2 - %f, val3 - %c\n", test_st->val1, test_st->val2, test_st->val3); } return test_st; }
المكتبة هي نفسها تمامًا كما في المقالة ctypes .
CFFI
هذه مكتبة للعمل حصريًا مع C. من وصف هذه المكتبة:
تفاعل مع أي كود C تقريبًا من Python
تم العثور على بعض هذا تقريبا.
للتجربة ، تم استخدام الإصدار 1.12.3 ، يمكنك أن تقرأ عنها هنا .
قليلاً عن هذه المكتبة بكلمتين ، تقوم CFFI بإنشاء ارتباطها أعلى مكتبتنا وتجميعها في مكتبة سنعمل معها.
تركيب
pip3 تثبيت cffi
جمعية
النص البرمجي للبناء الذي سيجمع الرابط حول مكتبتنا.
build.py
import os import cffi if __name__ == "__main__": ffi = cffi.FFI()
الثعبان
مثال على العمل مع C من Python من خلال CFFI :
from cffi import FFI import sys import time
للعمل مع رمز C ++ ، تحتاج إلى كتابة ارتباط C له. توضح المقالة حول الطريقة من خلال ctypes كيفية القيام بذلك. الرابط أدناه.
إيجابيات وسلبيات CFFI
الايجابيات :
- بناء جملة بسيط عند استخدامه في بيثون
- لا حاجة لإعادة ترجمة مكتبة المصدر
سلبيات :
pybind11
على النقيض من ذلك ، تم تصميم pybind11 خصيصًا للعمل مع C ++ . تم استخدام الإصدار 2.3.0 للتجربة ، يمكنك أن تقرأ عنها هنا . إنها لا تجمع مصادر C ، لذلك قمت بترجمتها إلى مصادر C ++.
تركيب
pip3 تثبيت pybind11
جمعية
نحن بحاجة إلى كتابة نص بناء لمكتبتنا.
build.py
import pybind11 from distutils.core import setup, Extension ext_modules = [ Extension( '_test',
نقوم بتنفيذها:
python3 setup.py build --build-lib=./lib
C ++
في مصدر المكتبة ، تحتاج إلى إضافة:
namespace py = pybind11;
الثعبان
مثال على العمل مع C من Python عبر pybind11 :
import sys import time
إيجابيات وسلبيات pybind11
الايجابيات :
- بناء جملة بسيط عند استخدامه في بيثون
سلبيات :
- تحتاج إلى تحرير مصادر C ++ ، أو كتابة ارتباط لهم
- من الضروري جمع المكتبة اللازمة من المصدر
يبدأ متوسط وقت تنفيذ الاختبار في كل طريقة بـ 1000:
- ctypes: - 0.0004987692832946777 seconds ---
- CFFI: - 0.00038521790504455566 ثانية ---
- pybind: - 0.0004547207355499268 ثانية ---
+ ، - لأن النتائج كانت مختلفة قليلاً في كل مرة. بالإضافة إلى ذلك ، فقد قضيت وقتًا في الطباعة ، وكنت كسولًا جدًا لإيقاف تشغيله (خذ هذا الوقت بثبات ، لأنه سيكون تقريبًا في جميع الاختبارات). ولكن لا يزال ، هناك فرق زمني في استدعاءات الوظائف والحصول على النتائج منها.
مراجع