基础部分请参考dalao写的这篇博客,本篇博客主要学习各类数据的交互。
普通数据
主要指的是int
、float
和char
之类的,举个例子:
在python文件中
import ctypes
lib = ctypes.cdll.LoadLibrary("D:/360MoveData/Users/Erick/Desktop/Dll/x64/Debug/Dll.dll")
print(lib.func(ctypes.c_int(10)))
在DLL.cpp中复制下面的文件:
// Dll.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
// Dll2.cpp: 定义 DLL 应用程序的导出函数。
#define EXPORT __declspec(dllexport)
#include<iostream>
using namespace std;
extern "C" {
EXPORT double func(int x) {
cout << "Get arg: " << x << endl;
return 3.14;
}
}
为了保证精度,都使用double
类型的数据。编译完成后,执行python文件,即可输出:
Get arg: 10
3.14
数组类型的数据
传入数组
向C语言函数传递数组数据:
import ctypes
lib = ctypes.cdll.LoadLibrary("D:/360MoveData/Users/Erick/Desktop/Dll/x64/Debug/Dll.dll")
INPUT = ctypes.c_int * 9 # 相当于声明了长度为9的数据
input = INPUT()
ls = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
t = 0
for i in range(3):
for j in range(3):
input[t] = ls[i][j]
t += 1
lib.read(input)
在C语言函数中:
#include "stdafx.h"
// Dll2.cpp: 定义 DLL 应用程序的导出函数。
#define EXPORT __declspec(dllexport)
#include<iostream>
using namespace std;
extern "C" {
EXPORT void read(int* arr) {
for (int i = 0; i < 9; ++i) {
cout << arr[i] << " ";
}
cout << endl;
}
}
传出结构体、数组
C语言不能直接向Python返回数组,需要借助结构体进行实现,先看python代码:
import ctypes
lib = ctypes.cdll.LoadLibrary("D:/360MoveData/Users/Erick/Desktop/Dll/x64/Debug/Dll.dll")
class MyStruct(ctypes.Structure):
_fields_ = [("name", ctypes.c_char * 10),
("score", ctypes.c_double),
("number", ctypes.c_int * 4)]
lib.foo.restype = ctypes.POINTER(MyStruct)
p = lib.foo()
print(p.contents.name)
print(p.contents.score)
ls = p.contents.number
for i in ls:
print(i)
注意两个地方,必须要继承ctype.Structure
,同时所有的结构必须是在_fields
这个域中,同时需要包括名字,因为后期需要使用名字进行索引。获取值的时候,在contents
这个域中获取。
再来看C++的代码:
// Dll.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include <stdint.h>
// Dll2.cpp: 定义 DLL 应用程序的导出函数。
#define EXPORT __declspec(dllexport)
#include<iostream>
using namespace std;
struct MyStructure {
char name[10];
double score;
int number[4];
};
extern "C" {
EXPORT MyStructure* foo() {
auto p = new MyStructure;
p->name[0] = 'T';
p->name[1] = 'o';
p->name[2] = 'm';
p->name[3] = '\0';
p->score = 98.383;
p->number[0] = 1;
p->number[1] = 0;
p->number[2] = 0;
p->number[3] = 1;
return p;
}
}