参考
C/C++部分
将C/C++代码编译为DLL动态链接库
新建C/C++项目时选择 动态链接库
话不多说,直接上代码
C部分
#include "stdio.h"
#define EXPORT extern "C" __declspec(dllexport)
EXPORT typedef struct PathP {
int x;
int y;
int sum;
}Path;
EXPORT Path add(int x, int y) {
Path p;
p.x = x;
p.y = y;
p.sum = x + y;
printf("sum done\n");
return p;
}
为了方便我写的粗糙些,大概就是extern “C” 和 __declspec(dllexport)前缀表示外部代码调用dll可以调用的函数,若不加即使被编译成dll则此函数也不能外部被调用(没仔细深究过,若有错误请指出)
这里写了一个add函数返回一个包含x,y,sum的path结构体。
编译之后会生成一个dll文件
经过我多次尝试发现
在用ctypes调用C函数时
只能返回基本类型和结构体
不能返回多维数组
结构体不能有动态数组
同时,传入参数时
可以传入定长多维数组
不能传入动态数组(值会错乱)
也可能是我技术不到位,方法不对。。。若有大佬会的请指正
更多类型参数传入参考:python 调用C++,传递int,char,char*,数组和多维数组3
Python部分
import ctypes
class StructPath(ctypes.Structure):
pass
StructPath._fields_ = [("x", ctypes.c_int), ("y", ctypes.c_int), ("sum", ctypes.c_int)]
test = ctypes.cdll.LoadLibrary("xxx.dll")
test.add.restype = StructPath
path = test.add(5, 6)
print(path.x)
print(path.y)
print(path.sum)
代码中定义了path结构体对象并继承于ctypes.Structure,对象不需要包含任何内容,所以直接pass。
将结构体的属性按照格式赋(定义)给结构体对象的_fields_ 字段。
同时函数的返回值restype也要定义为结构体对象,与C代码相对应。
最后,直接调用,收工。