概述
一、What is ctypes?
ctypes
是 Python 的外部函数库。它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装……
相信你可能会觉得这又是一篇从“入门到精通”类的文章。当然不是的nei~我就是记一下我觉得有价值的东东,你一定也会用得到,而且关注我的小伙伴们自然猜到我们为什么要用ctypes,嘻嘻????
详细的介绍可见:https://docs.python.org/zh-cn/3.7/library/ctypes.html
二、进阶之路,就在脚下
1.载入动态连接库
ctypes
导出了 cdll 对象,在 Windows 系统中还导出了 windll 和 oledll 对象用于载入动态连接库。
- cdll 载入按标准的
cdecl
调用协议导出的函数 - windll 导入的库按
stdcall
调用协议调用其中的函数 - oledll 也按
stdcall
调用协议调用其中的函数,并假定该函数返回的是 WindowsHRESULT
错误代码,并当函数调用失败时,自动根据该代码甩出一个OSError
异常。
因为一些后续工程的原因,我只在Windows下进行了试验:
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> print(ctypes.windll.kernel32)
<WinDLL 'kernel32', handle 7ffddd2e0000 at 0x1a265774308>
>>> print(ctypes.cdll.msvcrt)
<CDLL 'msvcrt', handle 7ffddd420000 at 0x1a2657617c8>
2.调用函数
(1)ctypes.windll.kernel32.VirtualAlloc函数。
VirtualAlloc是Windows提供的API,通常用来分配大块的内存。例如如果想在进程A和进程B之间通过共享内存的方式实现通信,可以使用该函数。不要用该函数实现通常情况的内存分配。该函数的一个重要特性是可以预定指定地址和大小的虚拟内存空间。例如,希望在进程的地址空间中第50MB的地方分配内存,那么将参数 50*1024*`1024 = 52428800 传递给pvAddress,将需要的内存大小传递给dwSize。如果系统有足够大的闲置区域能满足请求,则系统会将该块区域预订下来并返回预订内存的基地址,否则返回NULL。
格式:
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
};
ctypes
定义了一些和C兼容的基本数据类型:
ctypes 类型 | C 类型 | Python 类型 |
---|---|---|
|
| bool (1) |
|
| 单字符字节对象 |
|
| 单字符字符串 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 整型 |
|
| 浮点数 |
|
| 浮点数 |
|
| 浮点数 |
|
| 字节串对象或 |
|
| 字符串或 |
|
| int 或 |
(2)RtlMoveMemory从指定内存中复制内存至另一内存里 ,语法如下:
VOID RtlMoveMemory(
VOID UNALIGNED *Destination,
const VOID UNALIGNED *Source,
SIZE_T Length
);
Destination :指向移动目的地址的指针。
Source :指向要复制的内存地址的指针。
Length :指定要复制的字节数。
(3)CreateProcess
调用时,系统将创建一个进程和一个主线程。CreateThread将在主线程的基础上创建一个新线程,大致做如下步骤:
- 在内核对象中分配一个线程标识/句柄,可供管理,由CreateThread返回
- 把线程退出码置为STILL_ACTIVE,把线程挂起计数置1
- 分配context结构
- 分配两页的物理存储以准备栈,保护页设置为PAGE_READWRITE,第2页设为PAGE_GUARD
- lpStartAddr和lpvThread值被放在栈顶,使它们成为传送给StartOfThread的参数
- 把context结构的栈指针指向栈顶(第5步)指令指针指向startOfThread函数
语法:
hThread = CreateThread(&security_attributes, dwStackSize, ThreadProc,pParam, dwFlags, &idThread) ;
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes
DWORD dwStackSize, // initial thread stack size
LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function
LPVOID lpParameter, // argument for new thread
DWORD dwCreationFlags, // creation flags
LPDWORD lpThreadId // pointer to receive thread ID
);
第一个参数是指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中,它被设为NULL。
第二个参数是用于新线程的初始堆栈大小,默认值为0。在任何情况下,Windows根据需要动态延长堆栈的大小。
第三个参数是指向线程函数的指标。函数名称没有限制,但是必须以下列形式声明:DWORD WINAPI ThreadProc (PVOID pParam) ;
第四个参数为传递给ThreadProc的参数。这样主线程和从属线程就可以共享数据。
第五个参数通常为0,但当建立的线程不马上执行时为旗标CREATE_SUSPENDED。线程将暂停直到呼叫ResumeThread来恢复线程的执行为止。
第六个参数是一个指标,指向接受执行绪ID值的变量。
最后
以上就是生动蛋挞为你收集整理的[编程进阶]ctypes在Python编程中的奇光异彩一、What is ctypes?二、进阶之路,就在脚下的全部内容,希望文章能够帮你解决[编程进阶]ctypes在Python编程中的奇光异彩一、What is ctypes?二、进阶之路,就在脚下所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复