如何在python中创建等效结构并使用malloc更改空指针的引用

Posted

技术标签:

【中文标题】如何在python中创建等效结构并使用malloc更改空指针的引用【英文标题】:How to create equivalent struct in python and use malloc to change reference of null pointer 【发布时间】:2019-07-10 00:45:40 【问题描述】:

我正在使用 ctypes 将代码从 C++“翻译”为 python。通常我不会坐下来将代码从 C++ 翻译成 Python,但我正在从事的项目需要它。

原始C++代码有一个结构体,格式如下;

typedef struct 
        ViChar resourceString[256];
    BP2_DEVICE;

在主代码中,指针初始化如下;

BP2_DEVICE* resStr = 0;

然后分配内存;

resStr = (BP2_DEVICE *)malloc(256);

在网上搜索帮助时,我了解到创建一个类来表示 BP2_Device 结构体是可行的;

class BP2_Device:
    def __init__(self, resourceString):
        self.resourceString = resourceString

不过,我不确定如何将“resourceString”必须是一个可变数组这一事实结合起来。我知道将 resourceString 变成可变数组的代码如下;

resourceString = ct.create_string_buffer(256)

至于如何使它与结构/类一起工作,我不知道。

我还查看了 this 问题以寻求有关 malloc 的帮助,但他们的设置与我的不完全一样。

整个代码很长,我不想用它来淹没这个问题。如果有什么我需要补充澄清的,请告诉我。感谢您提供任何和所有帮助,谢谢。

【问题讨论】:

为显然至少有 256 个字节长度的内容分配 4 个字节是不会好的。 看起来他们正在尝试(但失败)构建一个可调整大小的数组。如果是这种情况,您可以只使用常规的旧列表或元组或字符串或任何有意义的东西。 如果你要将 C++ 代码翻译成 Python,为什么需要ctypes?它通常用于连接 C API。如果翻译成纯 Python,你只需要bytearray(256) 无论结构内容是什么,在 64bit 上,您都会有 Undefined Behavior(因为malloc(4))。 @SamVarshavchik 这是我的一个错字,意思是输入 256 而不是 4。 【参考方案1】:

这取决于您要如何使用该结构,但如果 resourceString 是一个以 null 结尾的字符串,则此方法有效:

from ctypes import *

class Bp2Device(Structure):
    _fields_ = [('resourceString',c_char * 256)]

dev = Bp2Device(b'some resource string')
print(dev.resourceString)
dev.resourceString = b'x' * 256 #works
dev.resourceString = b'x' * 257 #fails

输出:

b'some resource string'
Traceback (most recent call last):
  File "C:\test.py", line 9, in <module>
    dev.resourceString = b'x' * 257
ValueError: bytes too long (257, maximum length 256)

请注意,resourceString 是一个可写缓冲区,因此您可以将此结构传递给 C DLL 函数,它们可以安全地对其进行写入。 ctypes 专门处理 c_char * n 数组并将它们显示为 bytes,但由于这种特殊处理,您不能单独为数组的元素分配值。如果你想要可写的元素,使用c_ubyte * 256,但是你不能直接用字节字符串初始化数组。示例:

from ctypes import *

BYTEARRAY256 = c_ubyte*256

class Bp2Device(Structure):
    _fields_ = [('resourceString',BYTEARRAY256)]

b = BYTEARRAY256(*list(b'abcdefg'))
dev = Bp2Device(b)
dev.resourceString[6] = ord('x')
print(bytes(dev.resourceString))

输出:

b'abcdefx\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

【讨论】:

以上是关于如何在python中创建等效结构并使用malloc更改空指针的引用的主要内容,如果未能解决你的问题,请参考以下文章

在 LibreOffice Base 中创建等效数据透视表的 SQL (HSQLDB) 查询

在 ggplot2 中创建散点图矩阵(pairs() 等效)

如何在python中创建给定结构的元组[关闭]

Malloc 与创建数据结构

未指定子数组的数量时如何在C中创建数组数组? [复制]

如何在C++中创建一维动态数组