这个系列的内容都是大同小异的,每个篇章都在不断的完善,着急的同学可以直接看最新的篇章,博主建议是每一篇都看一遍,可以加深理解。
前言
由于c++运行速度相对于其他高级语言来说会比较快。使用python处理图像时可以考虑使用c++处理图像来提升运行速度。在ctypes里,可以把数组指针传递给dll,但是我们无法通过dll获取到c++返回的数组指针。由于python中没有对应的数组指针类型,因此,要获取dll返回的数组,我们需要借助结构体。
1、创建一个c++工程生成dll库
这里我们新建dll6_StructPointer文件
然后在选择配置管理器,选择X64
对源文件进行以下修改即可
源文件输入以下内容
Python调用C++程序时需要extern "C"来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。extern "C"在这里的作用相当于给c++程序披了一层c程序的外衣。
#include "pch.h"
#define DLLEXPORT extern "C" __declspec(dllexport) //放在 #include "stdafx.h" 之后
#include <string> //使用string类型 需要包含头文件 <string>
using namespace std; //string类是一个模板类,位于名字空间std中
typedef struct StructPointerTest
{
char name[20];
int age;
int arr[3];
int arrTwo[2][3];
}StructTest, * StructPointer;
//sizeof(StructTest)就是求 struct StructPointerTest 这个结构体占用的字节数
//malloc(sizeof(StructTest))就是申请 struct StructPointerTest 这个结构体占用字节数大小的空间
//(StructPointer)malloc(sizeof(StructTest))就是将申请的空间的地址强制转化为 struct StructPointerTest * 指针类型
//StructPointer p = (StructPointer)malloc(sizeof(StructTest))就是将那个强制转化的地址赋值给 p
StructPointer p = (StructPointer)malloc(sizeof(StructTest));
//字符串
DLLEXPORT StructPointer test() // 返回结构体指针
{
strcpy_s(p->name, "Lakers");
p->age = 20;
p->arr[0] = 3;
p->arr[1] = 5;
p->arr[2] = 10;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
p->arrTwo[i][j] = i * 10 + j;
return p;
}
然后生成解决方案,或F5运行程序即可
会在路径x64/Debug目录下生成dll文件
我们只需要用python代码调用这个路径下的dll文件,或拷贝到python能调用的路径下。
比如路径是这样的
然后我们的python代码要这样写
# 返回结构体
import ctypes
path = r'./dll6_StructPointer.dll'
dll = ctypes.WinDLL(path)
#定义结构体
class StructPointer(ctypes.Structure): #Structure在ctypes中是基于类的结构体
_fields_ = [("name", ctypes.c_char * 20), #定义一维数组
("age", ctypes.c_int),
("arr", ctypes.c_int * 3), #定义一维数组
("arrTwo", (ctypes.c_int * 3) * 2)] #定义二维数组
#设置导出函数返回类型
dll.test.restype = ctypes.POINTER(StructPointer) # POINTER(StructPointer)表示一个结构体指针
#调用导出函数
p = dll.test()
print(p.contents.name.decode()) #p.contents返回要指向点的对象 #返回的字符串是utf-8编码的数据,需要解码
print(p.contents.age)
print(p.contents.arr[0]) #返回一维数组第一个元素
print(p.contents.arr[:]) #返回一维数组所有元素
print(p.contents.arrTwo[0][:]) #返回二维数组第一行所有元素
print(p.contents.arrTwo[1][:]) #返回二维数组第二行所有元素
然后启用python运行看看最后结果是否正常输出
可以看到最后结果是正常计算了,到此c++的dll算是完结了,相信各位也能熟练的应用各种场景中去了。