最近在做用python调用C++程序,因为C++程序是现成的,而且效率高。听着感觉不难,直接调用dll应该就成,等我着手做的时候,真是处处碰壁。
最开始的时候,百度一些资料,说python与c++的交互分为以下几种:
1、自己写一个接口程序,实现C++到python的映射,从而实现python的扩展。
2、利用工具包SWIG,这个方法真是简单,深得我心,在这个方法上耗时半天,最终弃之。
3、对C++程序生成dll文件,python利用自身带的包ctypes实现数据的传递,最终成功。
前两种方法我尝试后均以失败告终,因为C++与python交互时,我需要传递指针,以上两种方法我没搞懂怎么传递数据。还有一些别的方法像利用Boost、numpy等,实在是等不及了,刚开个头就放弃了。现在就说说亲测有效的方法,直接上代码:
my.cpp
#define EXPORT_MY_DLL #include "my.h" #include <stdio.h> #include <math.h> #include <iostream> using namespace std; MY_API void Add(int *L, int *R) { for (int i = 0; i < 2; i++) { L[i] += 5 * R[i]; R[i] += 1; } }my.h
#ifdef EXPORT_MY_DLL #define MY_API __declspec(dllexport) #else #define MY_API __declspec(dllimport) #endif extern "C" { MY_API void Add(int *, int *); }
关于如何创建DLL文件,就不详细说了,直接百度也是很方便的。
我想用python调用Add函数,我在程序里面写好接口就可以创建。详细见http://www.jb51.net/article/52513.htm
接下来写Python程序:
import numpy as np import ctypes from ctypes import * a = np.ones(2).astype(np.int) b = np.ones(2).astype(np.int) a_ctypes_ptr = cast(a.ctypes.data, POINTER(c_int)) #转换为ctypes,这里转换后的可以直接利用ctypes转换为c语言中的int*,然后在c中使用 b_ctypes_ptr = cast(b.ctypes.data, POINTER(c_int)) #转换为ctypes,这里转换后的可以直接利用ctypes转换为c语言中的int*,然后在c中使用 dll = cdll.LoadLibrary('mys.dll') dll.Add(a_ctypes_ptr,b_ctypes_ptr) for i in range(2): print(a_ctypes_ptr[i])
是的,就是这样!可以直接利用ctypes将python数据转换成C中的指针,然后传递给C,在C中使用,并且这种方法不需要再将指针传回来,直接在程序中对数组进行了修改,想要观察矩阵元素,直接对转换后的数据进行操作就成了!
真是激动人心!
SWIG的学习:
https://blog.csdn.net/u014689510/article/details/50393341
https://zhuanlan.zhihu.com/p/27851893
https://blog.csdn.net/ustczhang/article/details/78147215
Ctypes的学习:
https://blog.csdn.net/thesby/article/details/76283807
https://docs.python.org/3/library/ctypes.html
https://blog.csdn.net/linda1000/article/details/12623527