菜鸟笔记
提升您的技术认知

python 调用dll 详解-ag真人游戏

准备

将动态库与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')
网站地图