如何使用 ctypes 从缓冲区中读回?
How can I read back from a buffer using ctypes?
我有一个第三方库,我需要使用它的 python 脚本中的一个函数。这是:
ReadFromBlob(PVOID blob, INT blob_size, PCSTR section, PCSTR key, const void **buffer, UINT * size)
- blob - 一些指针?到要读取的字节
- blob_size - 以字节为单位的 blob 大小
- 部分和键 - 像“图片”这样的字符串值
- 缓冲区 - 要读取到的字节数
- size - 缓冲区大小
文档给出了如何使用它的示例:
UINT size = 0;
PVOID buffer = NULL;
ReadFromBlob(<blob>, <blob_size>, "MainImage", "Image", &buffer, &size);
我不熟悉 C,所以参数类型让我很困惑。我需要能够从 python 中的缓冲区中读取值。
这是我目前所拥有的:
from ctypes import *
lib = cdll.LoadLibrary(path_to_lib)
with open(filepath, 'rb') as file:
data = file.read()
blob_size = c_int(len(data))
blob = cast(c_char_p(data), POINTER(c_char * blob_size.value))
b = bytes()
size = c_uint(len(b))
buffer = cast(cast(b, c_void_p), POINTER(c_char * size.value))
lib.ReadFromBlob(blob, blob_size, b"MainImage", b"Image", buffer, pointer(size))
但我最后还是得到了一个空缓冲区。请帮助我。
看起来该函数根据部分和键以及 returns 指向 blob 数据和大小的指针在 blob 中搜索数据,所以我创建了一个测试函数,它只回显 blob 和大小作为输出参数:
#include <windows.h>
#include <stdio.h>
__declspec(dllexport)
void ReadFromBlob(PVOID blob, INT blob_size, PCSTR section, PCSTR key, const void **buffer, UINT * size) {
printf("section=\"%s\" key=\"%s\"\n",section,key);
*buffer = blob; // just echo back input data for example
*size = (UINT)blob_size;
}
类型看起来像 Windows 类型,并且 ctypes
有一个子模块 wintypes
,其中包含 Windows 定义,有助于正确设置类型。确保使用 Windows 类型的并行 ctypes
类型正确设置 .argtypes
和 .restype
。这有助于 ctypes
检查参数是否正确传递。
import ctypes as ct
from ctypes import wintypes as w
dll = ct.CDLL('./test')
# Note the parallels between C types and ctypes types.
# PVOID is just "pointer to void" and LPVOID mean the same thing, etc.
dll.ReadFromBlob.argtypes = w.LPVOID,w.INT,w.LPCSTR,w.LPCSTR,ct.POINTER(w.LPCVOID),w.LPUINT
dll.ReadFromBlob.restype = None
# storage for returned values, passed by reference as output parameters
buffer = w.LPCVOID()
size = w.UINT()
dll.ReadFromBlob(b'filedata',8,b'Section',b'Key',ct.byref(buffer),ct.byref(size))
print(ct.cast(buffer,ct.c_char_p).value,size.value)
输出显示接收到的部分和密钥,并打印返回的 blob 数据和大小:
section="Section" key="Key"
b'filedata' 8
我有一个第三方库,我需要使用它的 python 脚本中的一个函数。这是:
ReadFromBlob(PVOID blob, INT blob_size, PCSTR section, PCSTR key, const void **buffer, UINT * size)
- blob - 一些指针?到要读取的字节
- blob_size - 以字节为单位的 blob 大小
- 部分和键 - 像“图片”这样的字符串值
- 缓冲区 - 要读取到的字节数
- size - 缓冲区大小
文档给出了如何使用它的示例:
UINT size = 0;
PVOID buffer = NULL;
ReadFromBlob(<blob>, <blob_size>, "MainImage", "Image", &buffer, &size);
我不熟悉 C,所以参数类型让我很困惑。我需要能够从 python 中的缓冲区中读取值。 这是我目前所拥有的:
from ctypes import *
lib = cdll.LoadLibrary(path_to_lib)
with open(filepath, 'rb') as file:
data = file.read()
blob_size = c_int(len(data))
blob = cast(c_char_p(data), POINTER(c_char * blob_size.value))
b = bytes()
size = c_uint(len(b))
buffer = cast(cast(b, c_void_p), POINTER(c_char * size.value))
lib.ReadFromBlob(blob, blob_size, b"MainImage", b"Image", buffer, pointer(size))
但我最后还是得到了一个空缓冲区。请帮助我。
看起来该函数根据部分和键以及 returns 指向 blob 数据和大小的指针在 blob 中搜索数据,所以我创建了一个测试函数,它只回显 blob 和大小作为输出参数:
#include <windows.h>
#include <stdio.h>
__declspec(dllexport)
void ReadFromBlob(PVOID blob, INT blob_size, PCSTR section, PCSTR key, const void **buffer, UINT * size) {
printf("section=\"%s\" key=\"%s\"\n",section,key);
*buffer = blob; // just echo back input data for example
*size = (UINT)blob_size;
}
类型看起来像 Windows 类型,并且 ctypes
有一个子模块 wintypes
,其中包含 Windows 定义,有助于正确设置类型。确保使用 Windows 类型的并行 ctypes
类型正确设置 .argtypes
和 .restype
。这有助于 ctypes
检查参数是否正确传递。
import ctypes as ct
from ctypes import wintypes as w
dll = ct.CDLL('./test')
# Note the parallels between C types and ctypes types.
# PVOID is just "pointer to void" and LPVOID mean the same thing, etc.
dll.ReadFromBlob.argtypes = w.LPVOID,w.INT,w.LPCSTR,w.LPCSTR,ct.POINTER(w.LPCVOID),w.LPUINT
dll.ReadFromBlob.restype = None
# storage for returned values, passed by reference as output parameters
buffer = w.LPCVOID()
size = w.UINT()
dll.ReadFromBlob(b'filedata',8,b'Section',b'Key',ct.byref(buffer),ct.byref(size))
print(ct.cast(buffer,ct.c_char_p).value,size.value)
输出显示接收到的部分和密钥,并打印返回的 blob 数据和大小:
section="Section" key="Key"
b'filedata' 8