كتبت عن كيفية الاتصال بيثون من C في مقال سابق ، والآن دعونا نتحدث عن كيفية القيام بالعكس وندعو C / C ++ من Python3 . بمجرد أن بدأت الكتابة عن هذا ، سنكشف عن الموضوع بأكمله حتى النهاية. علاوة على ذلك ، لا يوجد شيء معقد هنا أيضًا.
C
كل شيء بسيط هنا ، يمكن لبيثون استدعاء وظائف C دون أي مشاكل.
test.c:
#include "test.h" int a = 5; double b = 5.12345; char c = 'X'; int func_ret_int(int val) { printf("get func_ret_int: %d\n", val); return val; } double func_ret_double(double val) { printf("get func_ret_double: %f\n", val); return val; } char * func_ret_str(char *val) { printf("get func_ret_str: %s\n", val); return val; } char func_many_args(int val1, double val2, char val3, short val4) { printf("get func_many_args: int - %d, double - %f, char - %c, short - %d\n", val1, val2, val3, val4); return val3; }
test.h:
#ifndef _TEST_H_ #define _TEST_H_ #ifdef __cplusplus extern "C" { #endif #include <stdio.h> #include <string.h> #include <unistd.h> 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) #ifdef __cplusplus } #endif #endif /* _TEST_H_ */
كيفية التجميع:
gcc -fPIC -shared -o libtest.so test.c
المصدر يجمع مكتبة ديناميكية وهو جاهز للمعركة.
نمر إلى بيثون. يوضح المثال كيفية تمرير الوسائط إلى دالة ، والحصول على نتيجة دالة ، وكيفية الحصول على قيم المتغيرات العامة وتغييرها.
main.py:
يمكن العثور على جميع أنواع البيانات الممكنة وتسمياتها في وثائق Python.
العمل مع الهياكل
ج - إعلان هيكل في test.h:
typedef struct test_st_s test_st_t; struct test_st_s { int val1; double val2; char 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; }
الثعبان:
import sys import struct
C ++
الأمر أكثر تعقيدًا هنا ، لأن ctypes يمكن أن تعمل فقط مع وظائف C. هذه ليست مشكلة بالنسبة لنا ، فقط C سيربط رمز C ++.
أساليب فئة C ++ وربط C:
#include "test.hpp" std::string test::ret_str(std::string val) { std::cout << "get ret_str: " << val << std::endl; return val; } int test::ret_int(int val) { std::cout << "get ret_int: " << val << std::endl; return val; } double test::ret_double(double val) { std::cout << "get ret_double: " << val << std::endl; return val; } /* * C C++ */ // test, . test *test_new() { return new test(); } // test. void test_del(test *test) { delete test; } /* * . */ // ret_str char *test_ret_str(test *test, char *val) { // char * std::string std::string str = test->ret_str(std::string(val)); // std::string char * char *ret = new char[str.length() + 1]; strcpy(ret, str.c_str()); return ret; } // ret_int int test_ret_int(test *test, int val) { return test->ret_int(val); } // ret_double double test_ret_double(test *test, double val) { return test->ret_double(val); } /* * . */ // a int test_get_a(test *test) { return test->a; } // b double test_get_b(test *test) { return test->b; } // c char test_get_c(test *test) { return test->c; }
ولكن هناك تحذير واحد ، يجب الإعلان عن الارتباط بأنه خارجي C. بحيث لا يزيد برنامج التحويل البرمجي ++ أسماء دالة الربط. إذا فعل ذلك ، فلن نكون قادرين على العمل مع وظائفنا من خلال ctypes.
test.hpp:
#include <iostream> #include <string.h> class test { public: int a = 5; double b = 5.12345; char c = 'X'; std::string ret_str(std::string val); int ret_int(int val); double ret_double(double val); }; #ifdef __cplusplus extern "C" { #endif test *test_new(); void test_del(test *test); char *test_ret_str(test *test, char *val); int test_ret_int(test *test, int val); double test_ret_double(test *test, double val); int test_get_a(test *test); double test_get_b(test *test); char test_get_c(test *test); #ifdef __cplusplus } #endif
كيفية التجميع:
g ++ -fPIC -shared -o libtestpp.so test.cpp
بيثون بنفس السهولة.
إيجابيات وسلبيات ctypes
الايجابيات :
- يمكنك الاتصال بأي مكتبة C المترجمة بالفعل
سلبيات :
- في Python ، تحتاج إلى وصف وظائف C التي تُرجع وتقبل كوسائط.
حاول الرمز التعليق بوضوح ، لكتابة أقل هنا)
آمل أن يكون مفيدا.
شكر
DollaR84 لمساعدته.
Palich239 عن الأخطاء التي تم العثور عليها.
مراجع