python 调用dll 详解

这篇具有很好参考价值的文章主要介绍了python 调用dll 详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

准备

将动态库与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:在数组后面添加数据文章来源地址https://www.toymoban.com/news/detail-631950.html

字符串

// .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 <string.h>

#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')

到了这里,关于python 调用dll 详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 不同编程语言下CH347DLL的调用方法

            CH347为一款USB转JTAG/SPI/IIC/GPIO/UART接口的转换芯片,此处总结一下开发时所遇到的在C/C++、Python、C#下调用CH347DLL的方法,若有其他需要补充的也可一起交流。         基于WCH官方Demo板做的代码验证。         可参考WCH官网CH347EVT/Tools下工程代码,此处则不再重复    

    2024年02月16日
    浏览(38)
  • R语言无法调用stats.dll的问题解决方案[补充]

    在去年10月份,出过一起关于R语言无法调用stats.dll的问题解决方案,今天(你看到后是昨天)不知道为什么,安装包,一直安装不了,真的是炸裂了。后面再次把R与Rstuido升级。说实话,我是真不想折腾升级这些,因为,只要升级,环境多多少少 可能 会有变化,这次,我就是

    2024年02月15日
    浏览(52)
  • Python调用动态链接库(DLL)

    Python调用动态链接库(DLL) 动态链接库(Dynamic Link Libraries,简称DLL)是一种被多个程序共享的库文件,可以被用于将程序分解为小模块,减少内存占用,加快程序运行速度。而Python作为一种高级编程语言,可以方便地调用外部的DLL文件。 在Python中,可以使用ctypes模块来调用

    2024年02月13日
    浏览(52)
  • C++&Python&C# 三语言OpenCV从零开发(6):边界填充+Csharp调用Python matplotlib代码

    C++PythonCsharp in OpenCV 专栏 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程(附带课程课件资料+课件笔记) 今天来接着学习OpenCV,现在主要是以Python代码为主了,所以先实现Python,在用C++/Csharp重现一遍。 边界填充就是向外填充图片信息,将图片扩大。填充分为上下

    2024年01月23日
    浏览(66)
  • visual studio编写DLL,python调用

    选择第一个c++ DLL, 然后项目源文件下右击新建项,这里名字随便取,在代码中输入一下内容: 在visual studio的项目右击属性 选择不使用编译头,然后点击点击生成解决方案 就可以生成DLL文件了 (PS:前面截图代码忘记添加EXPORT,请参考代码框的代码) 然后python调用即可 如果

    2024年02月09日
    浏览(48)
  • 在python中通过调用dll来提高运行速度

    最近项目中需要录制键鼠命令,然后再通过注入的方式回放录制过程。一般来说,普通的一些点击命令完全可以通过python的一些包来完成键鼠模拟操作,比如通过pyautogui包。但是,鼠标移动过程中,如果采用频率很高的话,比如1s之类采样50个点像素坐标,那么就会发现,如果

    2024年02月12日
    浏览(35)
  • 【开发语言】C语言与Python的互操作详解

    博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客内容主要围绕:        5G/6G协议

    2024年02月10日
    浏览(66)
  • Python 使用 ctypes 调用 C/C++ DLL 动态链接库

    ctypes 有以下优点: Python内建,不需要单独安装 Python可以直接调用C/C++ 动态链接库(.dll 或 .so) 在Python一侧,不需要了解 c/c++ dll 内部的工作方式 提供了 C/C++ 数据类型与Python类型的相互映射,以及转换,包括指针类型。 ctypes 在下列场景可以发挥较大作用 运算量大的操作可以写

    2024年02月06日
    浏览(51)
  • [Python] 如何通过ctypes库来调用C++ 动态库 DLL?

    ctypes是Python的一个外部库,它提供了一种灵活的方式来调用C语言的动态链接库(DLL)或共享库(SO)。通过ctypes,我们可以在Python中直接调用 C语言编写的函数和变量 ,从而实现跨语言的互操作。 ctypes 它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模

    2024年01月19日
    浏览(38)
  • 自己开发jlink烧录软件,烧录上位机, C#调用JLinkARM.dll实现软件烧录

    最近需要写一个烧录软件,让工厂可以实现一键烧录。 这里实现了运行一个bat文件进行一键烧录,不想看这部分的可以直接跳到第二部分,不受影响。 由于jlink的自带烧录软件JFlash.exe操作十分繁杂,需要自己开发一个简洁的烧录方法,一番操作发现,可以使用J-Link Commander

    2024年04月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包