python调用C/C++
现在开源库中经常见到python和C/C++混用的情况,现在研究一下
python调用C/C++程序主要可以分为3步:
- 编写C/C++实现程序。
- 将C/C++程序编译成动态库。
- 在Python中调用编译生成的库。
python在调用C/C++程序时有一些不同,需要注意。
##原生态实现 ###python调用C
将C语言程序编译好,再使用python中的ctypes模块调用即可。
####编写C源文件
//test.c #include<stdio.h> int foo(int a, int b){ printf("a:%d, b:%d\n", a, b); return 0; }
####编译C源文件
//先生成test.o文件;然后编译为动态库test.so gcc -o test.so -shared -fPIC test.c
生成test.so动态库文件,之后就可以在Python中调用foo函数。
这里是生成的动态库: 静态库:libxxx.a 在程序编译的时候,将库编译进可执行程序中, 运行的时候不需要外部函数库 动态库:libxxx.so 在程序运行的时候,将库加载到程序中,运行的时候需要外部函数库
####python调用编译的库
import ctypes dll = ctypes.cdll.LoadLibrary lib = dll('./test.so') //刚刚生成的库文件的路径 lib.foo(1, 3)
输出:
###python调用C++
由于C支持函数重载,用g编译C时编译器会给函数的名称附加上额外的信息,这样ctypes模块就会找不到g编译生成的函数。因此,要让g++按照C语言的方式编译才可以找到生成的函数名。让编译器以C语言的方式编译就要在代码中使用extern关键字将代码包裹起来。
####编写c++源程序
//test.cpp #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(int a) { obj.display(a); } }
####编译c++源程序
g++ -o test.so -shared -fPIC test.cpp
编译参数说明:
- -fPIC:生成位置无关目标代码,适用于动态连接;
- -L path:表示在path目录中搜索库文件,如-L.表示在当前目录;
- -I path:表示在path目录中搜索头文件;
- -o file:制定输出文件为file;
- -shared:生成一个共享库文件;
####python调用编译库
import ctypes dll = ctypes.cdll.LoadLibrary lib = dll('../C++/test.so') lib.display() lib.display_int(0)
输出:
##使用boost实现 首先boost是一个C++第三方开源库,参考:C++:Boost库。这里使用的是其中的跨语言混合编程功能
###编写C++源程序
#include <boost/python/module.hpp> #include <boost/python/def.hpp> using namespace boost::python; int Add(const int x, const int y) { return x + y; } int Del(const int x, const int y) { return x - y; } BOOST_PYTHON_MODULE(test2) { def("Add", Add); def("Del", Del); }
###编译C++源程序
g++ test.cpp -fPIC -shared -o test.so -I/usr/bin/python2.7 -I/usr/local/include -L/usr/local/lib -lboost_python
编译时需要指定boost头文件和库的路径,我这里分别是/usr/local/include和/usr/local/lib
(1)报错1 办法:
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
(2)报错2 还未解决
###python引入链接库
>>> import test2 >>> test2.Add(1,2) 3 >>> test2.Del(1,2) -1
##参考 1、简单的Python调用C++程序 2、c语言将程序写为动态库,C语言函数篇(五)静态库和动态库的创建和使用 3、Python调用C++程序的几种方法
- python调用c++ ctype list传数组 或者 返回数组
- C++中调用Python脚本(转载)
- Boost.Python3将C++代码封装为Python模块,并在Python中调用封装的动态库so文件cmake, boost, opencv3,numpy
- c++调用python文件找不到python35_d.lib
- python和C/C++的互相调用 VC
- Python和C|C++的混编(一):Python调用C、C++---Boost库
- 使用C++调用Python代码的方法步骤
- Python调用C/C++(使用SWIG)
- python调用c++动态库(2)
- 【Cython】用Cython包装C++代码,提供给python调用
- Python调用C/C++的种种方法
- Python调用C++程序的方法详解
- C++ 多线程调用Python脚本
- 不安装Python的情况下用C++调用Python
- 利用thrift在c++、java和python之间相互调用
- 如何在C++代码中调用python代码(MinGW+Boost.Python)
- c++调用python的入门例子
- C++调用PythonAPI线程状态和全局解释器锁
- python下面通过ctypes模块调用c++库的方法
- python与C/C++互相调用