怎样让Python脚本与C++程序互相调用
发布网友
发布时间:2022-04-21 04:39
我来回答
共1个回答
热心网友
时间:2023-11-05 16:17
二、Python调用C/C++\x0d\x0a\x0d\x0a\x0d\x0a1、Python调用C动态链接库\x0d\x0a\x0d\x0a Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可。\x0d\x0a(1)C语言文件:pycall.c\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0a/***gcc -o libpycall.so -shared -fPIC pycall.c*/ \x0d\x0a#include
\x0d\x0a#include \x0d\x0aint foo(int a, int b) \x0d\x0a{ \x0d\x0a printf("you input %d and %d\n", a, b); \x0d\x0a return a+b; \x0d\x0a} \x0d\x0a(2)gcc编译生成动态库libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++编译生成C动态库的代码中的函数或者方法时,需要使用extern "C"来进行编译。\x0d\x0a(3)Python调用动态库的文件:pycall.py\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0aimport ctypes \x0d\x0all = ctypes.cdll.LoadLibrary \x0d\x0alib = ll("./libpycall.so") \x0d\x0alib.foo(1, 3) \x0d\x0aprint '***finish***' \x0d\x0a(4)运行结果:\x0d\x0a\x0d\x0a\x0d\x0a2、Python调用C++(类)动态链接库 \x0d\x0a\x0d\x0a 需要extern "C"来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。不是用extern "C",构建后的动态链接库没有这些函数的符号表。\x0d\x0a(1)C++类文件:pycallclass.cpp\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0a#include \x0d\x0ausing namespace std; \x0d\x0a \x0d\x0aclass TestLib \x0d\x0a{ \x0d\x0a public: \x0d\x0a void display(); \x0d\x0a void display(int a); \x0d\x0a}; \x0d\x0avoid TestLib::display() { \x0d\x0a cout<<"First display"<\x0d\x0a#include \x0d\x0a#include \x0d\x0a \x0d\x0aint fac(int n) \x0d\x0a{ \x0d\x0a if (n < 2) return(1); /* 0! == 1! == 1 */ \x0d\x0a return (n)*fac(n-1); /* n! == n*(n-1)! */ \x0d\x0a} \x0d\x0a \x0d\x0achar *reverse(char *s) \x0d\x0a{ \x0d\x0a register char t, /* tmp */ \x0d\x0a *p = s, /* fwd */ \x0d\x0a *q = (s + (strlen(s) - 1)); /* bwd */ \x0d\x0a \x0d\x0a while (p < q) /* if p < q */ \x0d\x0a { \x0d\x0a t = *p; /* swap & move ptrs */ \x0d\x0a *p++ = *q; \x0d\x0a *q-- = t; \x0d\x0a } \x0d\x0a return(s); \x0d\x0a} \x0d\x0a \x0d\x0aint main() \x0d\x0a{ \x0d\x0a char s[BUFSIZ]; \x0d\x0a printf("4! == %d\n", fac(4)); \x0d\x0a printf("8! == %d\n", fac(8)); \x0d\x0a printf("12! == %d\n", fac(12)); \x0d\x0a strcpy(s, "abcdef"); \x0d\x0a printf("reversing 'abcdef', we get '%s'\n", \ \x0d\x0a reverse(s)); \x0d\x0a strcpy(s, "madam"); \x0d\x0a printf("reversing 'madam', we get '%s'\n", \ \x0d\x0a reverse(s)); \x0d\x0a return 0; \x0d\x0a} \x0d\x0a 上述代码中有两个函数,一个是递归求阶乘的函数fac();另一个reverse()函数实现了一个简单的字符串反转算法,其主要目的是修改传入的字符串,使其内容完全反转,但不需要申请内存后反着复制的方法。\x0d\x0a(2)用样板来包装代码\x0d\x0a 接口的代码被称为“样板”代码,它是应用程序代码与Python解释器之间进行交互所必不可少的一部分。样板主要分为4步:a、包含Python的头文件;b、为每个模块的每一个函数增加一个型如PyObject* Mole_func()的包装函数;c、为每个模块增加一个型如PyMethodDef MoleMethods[]的数组;d、增加模块初始化函数void initMole()。