C结构=>ctypes结构。。。这个映射正确吗?

2024-10-02 02:32:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从Python访问两个用C编写的旧的de/compression函数,它们目前可以通过DLL(我有C源代码)使用。在

函数被传递给一个(部分)填充的C结构,并使用此信息来压缩或解压缩提供的缓冲区中的数据。在

这就是函数的调用方式。为了与Python兼容,我添加了-uucdecl。在

// Both functions return 0 on success and nonzero value on failure
int __cdecl pkimplode(struct pkstream *pStr);
int __cdecl pkexplode(struct pkstream *pStr);

下面是C中定义的pkstream结构:

^{pr2}$

这是我在Python中镜像这个结构的尝试。在

# Define the pkstream struct
class PKSTREAM(Structure):
   _fields_ = [('pInBuffer', c_ubyte),
               ('nInSize', c_uint),
               ('pOutBuffer', c_ubyte),
               ('nOutSize', c_uint),
               ('nLitSize', c_ubyte),
               ('nDictSizeByte', c_ubyte),
               ('pInPos', c_ubyte),
               ('pOutPos', c_ubyte),
               ('nBits', c_ubyte),
               ('nBitBuffer', c_ulong),
               ('pDictPos', c_ubyte),
               ('nDictSize', c_uint),
               ('nCurDictSize', c_uint),
               ('Dict', c_ubyte)]

对于以下问题,我非常感谢您的帮助(我选择在前端提出问题,而不是仅仅“胡扯”,希望有明显的原因):

  1. 我不确定是对unsigned char类型的成员使用c\ubyte、c\u char还是c\u char_p。cuubyte最接近于unsigned char的ctypes(至少根据文档),但实际上是一个?内景/长线?在Python中。

  2. 有时成员是指向无符号字符的指针。。。这张地图能映射到c\u char\p吗?ctypes文档说所有字节和unicode字符串都作为指针传递,那么我需要对此做些什么规定呢?

  3. 我需要为函数提供pOutBuffer,它应该是指向分配内存的位置的指针,函数可以将解压缩/压缩数据复制到该位置。我想我应该使用create_string_buffer()来创建一个大小合适的缓冲区?

  4. 我还需要知道如何定义成员Dict[0x1000],它(在我看来)是创建一个4096字节的缓冲区,供函数内部使用。我知道我的定义显然是错误的,但不知道该如何定义?

  5. C函数应该被修饰成\uu stdcall还是\uu cdecl?(我已经在一些测试DLL上使用了后者,因为我一直在努力达到这一点)。

如有任何反馈,我们将不胜感激!在

提前谢谢你

詹姆斯


Tags: 数据函数定义on成员结构struct缓冲区
1条回答
网友
1楼 · 发布于 2024-10-02 02:32:18

如果在Python结构中有一个指针,那么也可以声明它是一个指针。在

一种方法是在ctypes中使用POINTER实用程序—它是一个比ctypes.c_char_p更高级别的对象(并且与此不完全兼容),但是您的代码将变得更具可读性。另外,对于模拟C数组,基ctypes类型可以乘以一个标量,返回的对象是可以用作相同大小的基类型的C向量的对象-(因此Dict字段可以定义为如下,c_ubyte * 4096

注意,虽然char等同于c_ubyte,但是int相当于{},而不是{},同样地,long。在

结构定义没有声明指向的缓冲区是const。如果您传递了一个python字符串(不可变),而您的库试图更改它,则会得到错误。相反,您应该传递从create_string_buffer返回的可变内存,该内存由字符串初始化。在

POINTER = ctypes.POINTER
# Define the pkstream struct
class PKSTREAM(Structure):
   _fields_ = [('pInBuffer', POINTER(c_char)),
               ('nInSize', c_int),
               ('pOutBuffer', POINTER(c_char)),
               ('nOutSize', c_int),
               ('nLitSize', c_char),
               ('nDictSizeByte', c_char),
               ('pInPos', POINTER(c_char)),
               ('pOutPos', POINTER(c_char)),
               ('nBits', c_char),
               ('nBitBuffer', c_long),
               ('pDictPos', POINTER(c_char)),
               ('nDictSize', c_int),
               ('nCurDictSize', c_int),
               ('Dict', c_char * 0x1000)]

至于(5),我不知道你应该如何装饰你的C函数-使用任何可行的。在

相关问题 更多 >

    热门问题