一、在vs2017年创建dll程序
1.新建项目,选择“windows桌面向导”
2.选择应用程序类型为dll,注意还要勾选“空项目”
3.在源文件夹里新建一个cpp,代码如下:
#define DLLEXPORT extern "C" __declspec(dllexport)
#include "stdio.h"
DLLEXPORT wchar_t* sum(wchar_t *str, int b, float f) {
static wchar_t a[] = L"你好,world";
static wchar_t szBuffer[100];
float x = b + f;
swprintf(szBuffer, 255,L"%s,%s,%f", a, str, x);
return szBuffer;
}
注意:
1.这里返回的字符数组必须是static的,否则python读取为乱码
二.在pycharm里新建python项目并创建一个python文件,代码如下:
from ctypes import *
dll = CDLL('Project8.dll')
dll.sum.argtypes = [c_wchar_p,c_int,c_float]
dll.sum.restype = c_wchar_p
str = "come in";
pchar = dll.sum(str,2,3.215)
print(pchar)
注意:
1.这里主要使用了ctypes包来操作
2.通过CDLL引入dll
3.通过argtypes指定传入dll参数的类型,通过restype指定dll返回数据的类型,否则程序会因不知道数据类型而报错。
4.c_wchar表示宽字符类型,c_wchar_p表示宽字符数组的指针,其他同理。
三、向DLL传递结构体或DLL返回结构体
为了让dll和python间能传递结构体,需要在dll定义结构体,在python里定义对应的类
(一)dll的头文件里定义结构体
typedef struct MyS {
int a;
wchar_t *b;
} ms;
(二)dll的源文件代码
#define DLLEXPORT extern "C" __declspec(dllexport)
#include "stdio.h"
#include "MyStruct.h"
DLLEXPORT ms sum(ms m) {
ms n;
n.a = m.a * 2;
static wchar_t wc[100];
swprintf(wc, 255, L"%s,ok完成2", m.b);
n.b = wc;
return n;
}
说明:
1.由于结构体里有字符指针要返回,所以这里先创建了一个static的字符数组,再把地址传给结构体里的字符指针,这样python才能获得该字符串。
(三)python里代码如下:
from ctypes import *
class mss(Structure):
_fields_=[('a',c_int),
('b',c_wchar_p)]
dll = CDLL('Project8.dll')
dll.sum.argtypes = [mss]
dll.sum.restype = mss
x = mss()
x.a = 1
x.b = "你好hello3"
pchar = dll.sum(x)
print(pchar.a)
print(pchar.b)
说明:
1.通过类的方式定义了一个结构体
2.剩余的和上面简单例子一样。
3.这里的x.b是宽字符,因为python默认为utf-8,因此不会出错,但若x.b为窄字符,即c_char_p,注意要转换:x.b = "hello".encode("ansi")
4.在python里定义类时,成员有字符或字符指针的,一定要和dll结构体里的一致,要么全是指针,要么全是字符。