【python/ctypes】windows下调用动态库dll

说在前面

  • 环境:windows10
  • python版本:Python 3.7.3 [MSC v.1916 64 bit (AMD64)] on win32
  • visual studio版本:2017 community
  • 其他:在此之前,尝试过使用boost来链接,但是boost库过大,并不是很方便。linux下的使用方法类似。

简单函数返回

  • 下面的例子测试了intchar*的返回,例子比较简单,仅实现了返回。
  • 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

c_bool

_Bool

bool (1)

c_char

char

1-character bytes object

c_wchar

wchar_t

1-character string

c_byte

char

int

c_ubyte

unsigned char

int

c_short

short

int

c_ushort

unsigned short

int

c_int

int

int

c_uint

unsigned int

int

c_long

long

int

c_ulong

unsigned long

int

c_longlong

__int64 or long long

int

c_ulonglong

unsigned __int64 or unsigned long long

int

c_size_t

size_t

int

c_ssize_t

ssize_t or Py_ssize_t

int

c_float

float

float

c_double

double

float

c_longdouble

long double

float

c_char_p

char * (NUL terminated)

bytes object or None

c_wchar_p

wchar_t * (NUL terminated)

string or None

c_void_p

void *

int or None

关于性能

  • 如果对dll性能有要求,可以将编译的dll改为Release版本
    在这里插入图片描述

待续。。。。。。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值