【Python】Windows平台调用DLL中的方法

简介: 一、前言 我有一次在用Python开发项目工具的时候,需要用到一个加解密的模块。但是这个模块是纯C实现的,而且也是项目自己实现的算法,不可能有现成的Python库可以使用,当然我也不能用Python再写一遍。因此就想用Python调用C的接口,通过面向搜索引擎编程,找到了Python可以使用ctypes调用dll的方法,经过一番折腾后成功搞定。本篇文章特此记录一下之前学习的内容。

【Python】Windows平台调用DLL中的方法


一、前言


       我有一次在用Python开发项目工具的时候,需要用到一个加解密的模块。但是这个模块是纯C实现的,而且也是项目自己实现的算法,不可能有现成的Python库可以使用,当然我也不能用Python再写一遍。因此就想用Python调用C的接口,通过面向搜索引擎编程,找到了Python可以使用ctypes调用dll的方法,经过一番折腾后成功搞定。本篇文章特此记录一下之前学习的内容。


640.png


二、开始


       首先需要有一个DLL文件,如名为encrypt.dll的DLL文件,里面包含的接口定义在下面。然后我们开始一步步完成加载dll文件,并调用其中的方法。


// 创建一个加密解密对象, 通过传入的密钥
encrypt_obj* create(int key);
// 使用加密对象进行加密文本
void do_encrypt(encrypt_obj* obj, char* text, int size);
// 使用解密对象进行解密
void do_decrypt(encrypt_obj* obj, char* btext, int size);


   1. 加载dll


   一个简单的加载dll的代码如下:


import ctypes
encrypt_dll = ctypes.CDLL("encrypt.dll")


   我们知道dll的接口有stdcallcdecl两种调用约定,因此ctypes加载dll也有两种方式:


# stdcall
std_dll = ctypes.windll.LoadLibrary("dll")
std_dll = ctypes.WinDLL("dll")
# cdecl
cd_dll = ctypes.cdll.LoadLibrary("dll")
cd_dll = ctypes.CDLL("dll")
 
2.调用传参


   完成第一步的dll加载后,会返回这个dll的对象,现在我们就可以调用里面的方法了,例如:encrypt_dll.create(1)


   调用方法参数传递时,分基本类型和指针类型。基本的类型例如: int、float、char、short 这些都可以直接调用传入参数。但如果是指针类型,例如int*,就需要做一下转化,具体如下:


# 先创建一个int的对象
int_v = ctypes.c_int(1)
# 然后调用byref 作为指针传入方法中
dll.func(ctypes.byref(int_v))


   另外参数为char* 时,调用的代码如下:


# 1. 创建字符串
pstr = ctypes.c_char_p("string text")
# 或者
pstr = ctypes.c_char_p()
pstr.value = "string text"
# 2.然后调用传参
dll.func(ctypes.byref(pstr))


   如果既需要传入参数,也需要获取方法执行的返回值,而且不想像上面那样进行几步操作的话,可以使用下面的方式。在一开始就显示的定义好dll中的每个方法的传入参数类型,返回参数类型。这样就可以更方便的进行方法调用了。


# 先声明dll的这个方法的传入参数和返回值类型
encrypt_dll.create.argtypes = [c_int]
encrypt_dll.create.restypes = c_void_p
# 这样就可以直接调用
obj = encrypt_dll.create(1)
# 只定义传入参数类型,不定义返回值类型
encrypt_dll.do_encrypt.argtypes=[c_void_p,c_char_p,c_int]
# 定义好参数类型后,就可以直接传入参数了。
encrypt_dll.do_encrypt(obj, "aaa", 3)


   3. C基本类型和ctypes中类型映射表


c_char
char
c_short
short
c_int
int
c_long
long
c_ulong
unsigned long
c_float
float
c_double
double
c_void_p
void*


   针对表格前面7个,如果是指针类型时,就是在对应的类型后面加上"_p"。例如char* 就是c_char_p, int* 就是 c_int_p 等。


   4. 处理结构体


   如果有时候需要使用C的结构体,例如做一些赋值,读取数据的操作,这个时候就需要在Python中定义一个C的结构体类。以下是简单的一个例子。


// C语言中的结构体
typedef struct _myStruct
{
    int nValue;
    char szBuffer[128];
} MyStruct;


# Python中实现
import ctypes
class MyStruct(ctypes.Structure):
""" 继承自Structure """
  _fields_ = [
    ("nValue", ctypes.c_int),
    ("szBuffer", ctypes.c_char * 128)]
# 调用方式如下
dll = ctypes.CDLL("sample.dll")
my = MyStruct()
my.nValue = 123123
my.szBuffer = "string text"
dll.callfunc(ctypes.byref(my))


三、总结


   以上就是Python中调用Windows中的dll的方法,根据上面的方法我们就可以与C进行交互了,是不是很简单呢?希望看后对大家有帮助!


欢迎微信搜索"游戏测试开发"关注一起沟通交流。

相关文章
|
3月前
|
XML C# 数据格式
掌握了在Windows平台上查看DLL依赖的方法
掌握了在Windows平台上查看DLL依赖的方法
409 4
|
1月前
|
存储 缓存 安全
硬盘数据恢复:恢复硬盘数据的9个实用方法(Windows版)
无论是工作文档、家庭照片,还是其他珍贵的数字资产,数据丢失总是一件让人头疼的事情。然而,当硬盘发生问题时,不必过于慌张——只要正确应对,许多数据都可以被成功恢复。本文将从常见数据丢失原因到具体恢复方法,为您提供全面的硬盘数据恢复指导。
|
3月前
|
前端开发 数据可视化 API
Python实现智能家居设备的统一控制平台
【10月更文挑战第6天】 Python实现智能家居设备的统一控制平台
164 11
|
3月前
|
人工智能 JavaScript 网络安全
ToB项目身份认证AD集成(三完):利用ldap.js实现与windows AD对接实现用户搜索、认证、密码修改等功能 - 以及针对中文转义问题的补丁方法
本文详细介绍了如何使用 `ldapjs` 库在 Node.js 中实现与 Windows AD 的交互,包括用户搜索、身份验证、密码修改和重置等功能。通过创建 `LdapService` 类,提供了与 AD 服务器通信的完整解决方案,同时解决了中文字段在 LDAP 操作中被转义的问题。
|
3月前
|
弹性计算 数据安全/隐私保护 Windows
阿里云国际版无法远程连接Windows服务器的排查方法
阿里云国际版无法远程连接Windows服务器的排查方法
|
3月前
|
安全 Windows
Windows系统实现exe服务注册的方法都有哪些?
【10月更文挑战第5天】Windows系统实现exe服务注册的方法都有哪些?
612 0
|
16天前
|
安全 关系型数据库 MySQL
Windows Server 安装 MySQL 8.0 详细指南
安装 MySQL 需要谨慎,特别注意安全配置和权限管理。根据实际业务需求调整配置,确保数据库的性能和安全。
86 9
|
2月前
|
网络安全 Windows
Windows server 2012R2系统安装远程桌面服务后无法多用户同时登录是什么原因?
【11月更文挑战第15天】本文介绍了在Windows Server 2012 R2中遇到的多用户无法同时登录远程桌面的问题及其解决方法,包括许可模式限制、组策略配置问题、远程桌面服务配置错误以及网络和防火墙问题四个方面的原因分析及对应的解决方案。
127 4
|
2月前
|
监控 安全 网络安全
使用EventLog Analyzer日志分析工具监测 Windows Server 安全威胁
Windows服务器面临多重威胁,包括勒索软件、DoS攻击、内部威胁、恶意软件感染、网络钓鱼、暴力破解、漏洞利用、Web应用攻击及配置错误等。这些威胁严重威胁服务器安全与业务连续性。EventLog Analyzer通过日志管理和威胁分析,有效检测并应对上述威胁,提升服务器安全性,确保服务稳定运行。
|
2月前
|
监控 安全 网络安全
Windows Server管理:配置与管理技巧
Windows Server管理:配置与管理技巧
114 3