最近因项目原因需要使用python调用c/c++代码,网上查找资料后了解到可以使用如下方法调用c/c++。在此做个记录。
1.cython
可将pyx编译成.c文件,再由c编译成.pyd文件(windows)。例如有如下文件,
h.pyx如下,distutils部分是调用c++时需要的,用于指定用c++编译。
# distutils: language = c++
# distutils: sources = test.cpp
# distutils: include_dirs = .
cdef extern from "test.h":
int add(int a, int b)
cpdef int py_add(int a, int b):
return add(a, b)
test.cpp如下
#include<iostream>
using namespace std;
int add(int a, int b){
return a + b;
}
test.h如下
// test.h
#ifndef TEST_H
#define TEST_H
int add(int a, int b);
#endif // TEST_H
然后需要使用如下setup.py脚本
from setuptools import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("h.pyx"))
# 编译cython
# python setup.py build_ext --inplace
在命令行中执行如下命令便能生成一个对应名称的pyd文件。
python setup.py build_ext --inplace
然后便可在python中导入调用
from cythonPkg import h # type: ignore
if __name__ == '__main__':
a = 1
b = 2
res = h.py_add(a, b)
print(res)
2.ctypes
通过将c++代码编译成dll文件,通过ctype来加载dll库进行调用。例如有如下test.cpp。
#include<iostream>
using namespace std;
extern "C"{
__declspec(dllexport) int add(int a, int b){
return a + b;
}
}
在cmd中使用如下命令编译成dll。
g++ -shared -o test.dll -fPIC test.cpp
其中添加这一段是为了防止编译成dll时方法名出现前后缀 。
extern "C"{ __declspec(dllexport)}
然后在python中加载dll文件,并声明使用的函数参数和返回值类型后便可调用。
from ctypes import *
if __name__ == '__main__':
# 加载DLL库
dll = cdll.LoadLibrary('D:\\codes\\python\\quant\\demo\\cythonPkg\\test.dll')
# 设置函数参数类型和返回类型
dll.add.argtypes = [c_int, c_int]
dll.add.restype = c_int
# 调用函数
result = dll.add(2, 3)
print(result) # 输出应该是5