准备
将动态库与py文件放在同一目录下
引入ctypes库
from ctypes import *
加载动态库
dll=cdll('.\\interfacetest.dll')
数据类型
ctypes数据类型 | c数据类型 |
---|---|
c_char | char |
c_short | short |
c_int | int |
c_long | long |
c_ulong | unsigned long |
c_float | float |
c_double | double |
c_char_p | char* |
c_void_p | void* |
基本数据类型参数
// .cpp
// 普通加法
float add(float ina, float inb) {
return ina inb;
}
# .py
a=1.0
b=2.0
# 定义函数的此参数类型
dll.add.argtypes=[c_float,c_float]
# 定义函数的返回值类型,不能省略
dll.add.restype=c_float
# 调用dll中的函数
c=dll.add(a,b)
print('普通加法,结果为:',c,'\n')
# 输出
普通加法,结果为: 3.0
argtypes:定义函数的参数类型
restype:定义函数的返回值类型
指针类型参数
// .cpp
// 普通加法-指针输出结果
void add_ptrout(float ina, float inb, float* outc) {
*outc = ina inb;
}
# .py
a=3.0
b=4.0
c=c_float(0.0) # 不能省略
# pointer(c_float) 表示参数类型为float型指针
dll.add_ptrout.argtypes=[c_float,c_float,pointer(c_float)]
dll.add_ptrout(a,b,c)
# c是指针,c.value为输出的值
print('普通加法指针输出,结果为:',c.value)
print('c的类型为',c,'\n')
# 输出
普通加法指针输出,结果为: 7.0
c的类型为 c_float(7.0)
pointer(c_float): 表示参数类型为float型指针
一维动态数组参数
// .cpp
// 一维动态数组加法
void add_vec(float* ina, float* inb, float* outc, int nums) {
for (int idx = 0; idx < nums; idx) {
outc[idx] = ina[idx] inb[idx];
}
}
# .py
nums=10
a=(c_float*nums)()
b=(c_float*nums)()
c=(c_float*nums)()
for i in range(nums):
a[i]=i
b[i]=1.1
dll.add_vec.argtypes=[pointer(c_float),pointer(c_float),pointer(c_float)]
dll.add_vec(a,b,c,nums)
print('一维动态数组加法,结果为:')
for i in c:
print(i, end=" ")
print('\n')
一维动态数组加法,结果为:
1.100000023841858 2.0999999046325684 3.0999999046325684 4.099999904632568 5.099999904632568 6.099999904632568 7.099999904632568 8.100000381469727 9.100000381469727 10.100000381469727
二维静态数组参数
// .cpp
// 二维静态数组加法
void add_staticmatrix(float ina[2][3], float inb[2][3], float outc[2][3]) {
for (int r = 0; r < 2; r) {
for (int c = 0; c < 3; c) {
outc[r][c] = ina[r][c] inb[r][c];
}
}
}
# .py
rows=2
cols=3
temp1=c_float*cols
a=(temp1*rows)()
b=(temp1*rows)()
c=(temp1*rows)()
for i in range(rows):
for j in range(cols):
a[i][j]=i j
b[i][j]=0.5
dll.add_staticmatrix(a,b,c)
print('二维静态数组加法,结果为:')
for i in c:
for j in i:
print(j, end=" ")
print('')
print('\n')
二维静态数组加法,结果为:
0.5 1.5 2.5
1.5 2.5 3.5
二维动态数组参数
// .cpp
// 二维动态数组加法
void add_dynamicmatrix(float** ina, float** inb, float** outc, int rows, int cols) {
for (int r = 0; r < rows; r) {
for (int c = 0; c < cols; c) {
outc[r][c] = ina[r][c] inb[r][c];
}
}
}
# .py
rows=2
cols=3
a_matrix=[]
b_matrix=[]
c_matrix=[]
for i in range(rows):
temp1=(c_float*cols)()
for j in range(cols):
temp1[j]=i j 1
a_matrix.append(cast(temp1,pointer(c_float)))
temp2=(c_float*cols)()
for j in range(cols):
temp2[j]=0.5
b_matrix.append(cast(temp2,pointer(c_float)))
temp3=(c_float*cols)()
c_matrix.append(cast(temp3,pointer(c_float)))
a_ptr=(pointer(c_float)*rows)(*a_matrix)
b_ptr=(pointer(c_float)*rows)(*b_matrix)
c_ptr=(pointer(c_float)*rows)(*c_matrix)
dll.add_dynamicmatrix(a_ptr,b_ptr,c_ptr,rows,cols)
print('二维动态数组加法,结果为:')
for i in range(rows):
for j in range(cols):
print(c_ptr[i][j], end=" ")
print('')
print('\n')
# 输出
二维动态数组加法,结果为:
1.5 2.5 3.5
2.5 3.5 4.5
cast(temp1,pointer(c_float)): cast(obj, typ) 将一个ctypes实例转换为指向另一个ctypes数据类型的指针,参数obj是将转换成指针的实例(对象),typ是要转换成的指针类型。返回一个与obj引用相同块内存的指针。
append:在数组后面添加数据
字符串
// .cpp
// 字符串复制
void stringcopy(char* in, char* out) {
strcpy(out, in);
}
# .py
in_str=create_string_buffer(b'hello world.')
len=sizeof(in_str)
out_str=create_string_buffer(len)
dll.stringcopy(in_str,out_str)
print('字符串复制,结果为:',out_str.value,'测试成功!\n')
# 输出
字符串复制,结果为: b'hello world.' 测试成功!
完整代码
// interface.h
#ifndef interface_h
#define interface_h
#ifdef __cplusplus
extern "c" {
#endif
// 普通加法
_declspec(dllexport) float add(float ina, float inb);
// 普通加法-指针输出结果
_declspec(dllexport) void add_ptrout(float ina, float inb, float* outc);
// 一维动态数组加法
_declspec(dllexport) void add_vec(float* ina, float* inb, float* outc, int nums);
// 二维静态数组加法
_declspec(dllexport) void add_staticmatrix(float ina[2][3], float inb[2][3], float outc[2][3]);
// 二维动态数组加法
_declspec(dllexport) void add_dynamicmatrix(float** ina, float** inb, float** outc, int rows, int cols);
// 字符串修改
_declspec(dllexport) void stringmodify(char* str, int len);
// 字符串复制
_declspec(dllexport) void stringcopy(char* in, char* out);
#ifdef __cplusplus
}
#endif
#endif
// .cpp
#include "interface.h"
#include
#ifdef __cplusplus
extern "c" {
#endif // __cplusplus
// 普通加法
float add(float ina, float inb) {
return ina inb;
}
// 普通加法-指针输出结果
void add_ptrout(float ina, float inb, float* outc) {
*outc = ina inb;
}
// 一维动态数组加法
void add_vec(float* ina, float* inb, float* outc, int nums) {
for (int idx = 0; idx < nums; idx) {
outc[idx] = ina[idx] inb[idx];
}
}
// 二维静态数组加法
void add_staticmatrix(float ina[2][3], float inb[2][3], float outc[2][3]) {
for (int r = 0; r < 2; r) {
for (int c = 0; c < 3; c) {
outc[r][c] = ina[r][c] inb[r][c];
}
}
}
// 二维动态数组加法
void add_dynamicmatrix(float** ina, float** inb, float** outc, int rows, int cols) {
for (int r = 0; r < rows; r) {
for (int c = 0; c < cols; c) {
outc[r][c] = ina[r][c] inb[r][c];
}
}
}
// 字符串修改
void stringmodify(char* str, int len) {
for (int idx = 0; idx < len; idx) {
str[idx] = 1;
}
}
// 字符串复制
void stringcopy(char* in, char* out) {
strcpy(out, in);
}
#ifdef __cplusplus
}
#endif
# python
from ctypes import *
dll=cdll('.\\interfacetest.dll')
a=1.0
b=2.0
# 定义函数的此参数类型
dll.add.argtypes=[c_float,c_float]
# 定义函数的返回值类型,不能省略
dll.add.restype=c_float
# 调用dll中的函数
c=dll.add(a,b)
print('普通加法,结果为:',c,'\n')
a=3.0
b=4.0
c=c_float(0.0) # 不能省略
# pointer(c_float) 表示参数类型为float型指针
dll.add_ptrout.argtypes=[c_float,c_float,pointer(c_float)]
dll.add_ptrout(a,b,c)
# c是指针,c.value为输出的值
print('普通加法指针输出,结果为:',c.value)
print('c的类型为',c,'\n')
nums=10
a=(c_float*nums)()
b=(c_float*nums)()
c=(c_float*nums)()
for i in range(nums):
a[i]=i
b[i]=1.1
dll.add_vec.argtypes=[pointer(c_float),pointer(c_float),pointer(c_float)]
dll.add_vec(a,b,c,nums)
print('一维动态数组加法,结果为:')
for i in c:
print(i, end=" ")
print('\n')
rows=2
cols=3
temp1=c_float*cols
a=(temp1*rows)()
b=(temp1*rows)()
c=(temp1*rows)()
for i in range(rows):
for j in range(cols):
a[i][j]=i j
b[i][j]=0.5
dll.add_staticmatrix(a,b,c)
print('二维静态数组加法,结果为:')
for i in c:
for j in i:
print(j, end=" ")
print('')
print('\n')
rows=2
cols=3
a_matrix=[]
b_matrix=[]
c_matrix=[]
for i in range(rows):
temp1=(c_float*cols)()
for j in range(cols):
temp1[j]=i j 1
a_matrix.append(cast(temp1,pointer(c_float)))
temp2=(c_float*cols)()
for j in range(cols):
temp2[j]=0.5
b_matrix.append(cast(temp2,pointer(c_float)))
temp3=(c_float*cols)()
c_matrix.append(cast(temp3,pointer(c_float)))
a_ptr=(pointer(c_float)*rows)(*a_matrix)
b_ptr=(pointer(c_float)*rows)(*b_matrix)
c_ptr=(pointer(c_float)*rows)(*c_matrix)
dll.add_dynamicmatrix(a_ptr,b_ptr,c_ptr,rows,cols)
print('二维动态数组加法,结果为:')
for i in range(rows):
for j in range(cols):
print(c_ptr[i][j], end=" ")
print('')
print('\n')
in_str=create_string_buffer(b'hello world.')
len=sizeof(in_str)
dll.stringmodify(in_str,len)
print('字符串修改,结果为:',in_str.value,'测试成功!\n')
in_str=create_string_buffer(b'hello world.')
len=sizeof(in_str)
out_str=create_string_buffer(len)
dll.stringcopy(in_str,out_str)
print('字符串复制,结果为:',out_str.value,'测试成功!\n')