说在前面
- 环境:windows10
- python版本:Python 3.7.3 [MSC v.1916 64 bit (AMD64)] on win32
- visual studio版本:2017 community
- 其他:在此之前,尝试过使用boost来链接,但是boost库过大,并不是很方便。linux下的使用方法类似。
简单函数返回
- 下面的例子测试了
int
、char*
的返回,例子比较简单,仅实现了返回。 - c++
#include <iostream> void TestVoid() { std::cout << "void test func!" << std::endl; return; } int TestInteger() { int a = 10; std::cout << "integer return test func! " << a << std::endl; return a; } char* TestString() { char a[16] = "str a is a str!"; std::cout << "string return test func! " << a << std::endl; return a; } int main() { TestVoid(); TestInteger(); TestString(); } extern "C" { __declspec(dllexport) void PyTestVoid() { TestVoid(); } __declspec(dllexport) int PyTestInteger() { return TestInteger(); } __declspec(dllexport) char* PyTestString() { return TestString(); } }
- 编译成动态库
注意动态库的位版本与python位版本保持一致,例如python是64位,那么编译的动态库也需要64位,否则会报错。
- python代码
ctypes
无需安装,为内置库import ctypes # 找到编译的dll地址 lib = ctypes.cdll.LoadLibrary('C:/path/to/Project2.dll') # PyTestInteger为c++代码中定义的函数名 # 使用restype来确定返回值的类型 # 如果不使用restype确定,函数即使有返回值也不会得到返回 lib.PyTestInteger.restype = ctypes.c_int lib.PyTestString.restype = ctypes.c_char_p # 调用 lib.PyTestVoid() # 调用 a = lib.PyTestInteger() print('a =', a) # 调用 b = lib.PyTestString() print('b =', b)
- 输出
void test func! integer return test func! 10 a = 10 string return test func! str a is a str! b = b'str a is a str!' Process finished with exit code 0
简单参数
- c++代码
void TestIntegerParam(int a, int b) { std::cout << "integer param test! a = " << a << "b = " << b << std::endl; return; } void TestStringParam(std::string a) { std::cout << "string param test! a = " << a.c_str() << std::endl; return; } extern "C" { __declspec(dllexport) void PyTestIntegerParam(int a, int b) { TestIntegerParam(a, b); } __declspec(dllexport) void PyTestStringParam(char* a) { TestStringParam(a); } }
- python代码
import ctypes lib = ctypes.cdll.LoadLibrary('C:/path/to/Project2.dll') # 使用argtypes来定义函数的参数 lib.PyTestIntegerParam.argtypes = [ctypes.c_int, ctypes.c_int] lib.PyTestStringParam.argtypes = [ctypes.c_char_p] lib.PyTestIntegerParam(10, 1) # 可以试下不加encode lib.PyTestStringParam('i am a str!'.encode('utf-8'))
- 输出
integer param test! a = 10b = 1 string param test! a = i am a str! Process finished with exit code 0
类型定义
ctypes type | C type | Python type |
---|---|---|
| bool (1) | |
| 1-character bytes object | |
| 1-character string | |
| int | |
| int | |
| int | |
| int | |
| int | |
| int | |
| int | |
| int | |
| int | |
| int | |
| int | |
| int | |
| float | |
| float | |
| float | |
| bytes object or | |
| string or | |
| int or |
关于性能
- 如果对
dll
性能有要求,可以将编译的dll
改为Release
版本
待续。。。。。。