永发信息网

怎样让Python脚本与C++程序互相调用

答案:1  悬赏:0  手机版
解决时间 2021-02-06 17:50
怎样让Python脚本与C++程序互相调用
最佳答案
二、Python调用C/C++

1、Python调用C动态链接库

Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可。
(1)C语言文件:pycall.c

[html] view plain copy

#include <stdio.h>
#include <stdlib.h>
int foo(int a, int b)
{
printf("you input %d and %d\n", a, b);
return a+b;
}
(2)gcc编译生成动态库libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++编译生成C动态库的代码中的函数或者方法时,需要使用extern "C"来进行编译。
(3)Python调用动态库的文件:pycall.py

[html] view plain copy
import ctypes
ll = ctypes.cdll.LoadLibrary
lib = ll("./libpycall.so")
lib.foo(1, 3)
print '***finish***'
(4)运行结果:

2、Python调用C++(类)动态链接库

需要extern "C"来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。不是用extern "C",构建后的动态链接库没有这些函数的符号表。
(1)C++类文件:pycallclass.cpp

[html] view plain copy
#include <iostream>
using namespace std;

class TestLib
{
public:
void display();
void display(int a);
};
void TestLib::display() {
cout<<"First display"<<endl;
}

void TestLib::display(int a) {
cout<<"Second display:"<<a<<endl;
}
extern "C" {
TestLib obj;
void display() {
obj.display();
}
void display_int() {
obj.display(2);
}
}
(2)g++编译生成动态库libpycall.so:g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp。
(3)Python调用动态库的文件:pycallclass.py

[html] view plain copy
import ctypes
so = ctypes.cdll.LoadLibrary
lib = so("./libpycallclass.so")
print 'display()'
lib.display()
print 'display(100)'
lib.display_int(100)
(4)运行结果:

3、Python调用C/C++可执行程序
(1)C/C++程序:main.cpp

[html] view plain copy
#include <iostream>
using namespace std;
int test()
{
int a = 10, b = 5;
return a+b;
}
int main()
{
cout<<"---begin---"<<endl;
int num = test();
cout<<"num="<<num<<endl;
cout<<"---end---"<<endl;
}
(2)编译成二进制可执行文件:g++ -o testmain main.cpp。
(3)Python调用程序:main.py

[html] view plain copy
import commands
import os
main = "./testmain"
if os.path.exists(main):
rc, out = commands.getstatusoutput(main)
print 'rc = %d, \nout = %s' % (rc, out)

print '*'*10
f = os.popen(main)
data = f.readlines()
f.close()
print data

print '*'*10
os.system(main)
(4)运行结果:

4、扩展Python(C++为Python编写扩展模块)
所有能被整合或导入到其它python脚本的代码,都可以被称为扩展。可以用Python来写扩展,也可以用C和C++之类的编译型的语言来写扩展。Python在设计之初就考虑到要让模块的导入机制足够抽象。抽象到让使用模块的代码无法了解到模块的具体实现细节。Python的可扩展性具有的优点:方便为语言增加新功能、具有可定制性、代码可以实现复用等。
为 Python 创建扩展需要三个主要的步骤:创建应用程序代码、利用样板来包装代码和编译与测试。
(1)创建应用程序代码

[html] view plain copy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int fac(int n)
{
if (n < 2) return(1);
return (n)*fac(n-1);
}

char *reverse(char *s)
{
register char t,
*p = s,
*q = (s + (strlen(s) - 1));

while (p < q)
{
t = *p;
*p++ = *q;
*q-- = t;
}
return(s);
}

int main()
{
char s[BUFSIZ];
printf("4! == %d\n", fac(4));
printf("8! == %d\n", fac(8));
printf("12! == %d\n", fac(12));
strcpy(s, "abcdef");
printf("reversing 'abcdef', we get '%s'\n", \
reverse(s));
strcpy(s, "madam");
printf("reversing 'madam', we get '%s'\n", \
reverse(s));
return 0;
}
上述代码中有两个函数,一个是递归求阶乘的函数fac();另一个reverse()函数实现了一个简单的字符串反转算法,其主要目的是修改传入的字符串,使其内容完全反转,但不需要申请内存后反着复制的方法。
(2)用样板来包装代码
接口的代码被称为“样板”代码,它是应用程序代码与Python解释器之间进行交互所必不可少的一部分。样板主要分为4步:a、包含Python的头文件;b、为每个模块的每一个函数增加一个型如PyObject* Module_func()的包装函数;c、为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组;d、增加模块初始化函数void initModule()。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
对于圆柱和方柱这两种建筑结构常采用的外立面
A2驾驶证一次扣12分怎么办
加工齿轮和粉末冶金齿轮哪个工艺好?
富美驾校(江门蓬江)地址好找么,我有些事要过
笋不宜哪些人吃?
DNF新无影剑红眼用好吗?和什么装备冲突
三和社区居委会在什么地方啊,我要过去处理事
怎么看自己的车子型号
汽运驾校培训基地(江门蓬江)地址有知道的么?
【过年干什么】春节期间我们应该要干什么写一
老冯家小炒地址在什么地方,想过去办事
重庆北部新区有什么好玩的地方?
江城驾校(江门蓬江区)地址在什么地方,想过去
我昨晚做梦,梦见发生两场车祸,血溅到我身上
一新驾驶培训有限公司(江门蓬江)地址在什么地
推荐资讯
在模为12的系统中,8的补码是多少
请问特斯拉的无线发电技术与特斯拉线圈有什么
宇星通讯地址有知道的么?有点事想过去
please take it的后面可以跟什么单词
百度贴吧如何更换吧主?
手机进水,屏幕变成紫色,需不需要换屏幕
悦·容专业女子养生会所这个地址在什么地方,
电视机调成了hdmi1之后显示无信号 过了几分钟
国家电网淅川九重电力客户服务大厅在什么地方
英语的”world",为何要这样发音?
有一堆细的碎乱石是什么成语
我儿子缺金。我姓张。希望哪位大师给起个不错
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?