Python ctypes如何处理malloc/free



我正在尝试使用ctypes库将.cpp文件转换为.py。

一些基本的操作是有效的,但在使用typedef结构和malloc/free时我很吃力。

我得到了什么:

module.h:

typedef struct
{   
CHAR8 name[M_MODNAMELEN_A];       /**< Name of the module. */
} MODULE_NAME;
typedef struct
{
UINT16 countModules;       /**< Count of module names.*/
MODULE_NAME * names;       /**< Array of module names.     */
} MODULE_LIST;

program.cpp:

UINT16 countModules;
SINT32 ret = GetCountModules(targetHandle, &countModules);
if(ret!=M1C_OK)
return ret;
MODULE_LIST modList;
modList.names = (MODULE_NAME*)malloc(countModules * sizeof(MODULE_NAME));
// do some calculations
free( modList.names );

program.py:

from ctypes import *
c_lib = CDLL('libXXYY.so')
class MODULE_NAME(Structure):
_fields_ = [
('name', c_byte)
]
def __repr__(self):
return '({0})'.format(self.name)
class MODULE_LIST(Structure):
_fields_ = [
('countModules', c_uint),
('names', POINTER(MODULE_NAME))     ### Is this conversion correct?
]
def __repr__(self):
return '({0}, {1})'.format(self.x, self.y)
count_modules = c_uint()
ret = c_long(c_lib.GetCountModules(target_handle, byref(count_modules)))
if ret.value != M1C_OK:
return ret
# Up to here everything works fine..
# Allocating memory for the list of module names
modList = MODULE_LIST()
modList.names =  ### How to convert the malloc line?
## Some calcs
### How to convert the free( modList.names ); line?

蟒蛇跑得很好;modList.names=";线在那里我尝试了几种方法(例如:modList.names=(MODULE_NAME(count_modules.value*sizeof(MODULE_NAME((((,但我所有的尝试都失败了。

我应该如何将malloc行从cpp转换为python?

我应该如何将自由行从cpp翻译成python?

typedef结构到类的转换是否正确?特别是";MODULE_LIST";。

我应该如何将malloc行从cpp转换为python?

通常,一个返回类似MODULE_LIST的DLL会为您执行malloc,并提供了一个稍后释放它的功能,但如果您必须自己填写数组类型是通过将类型乘以大小来创建的,然后调用它来创建一个实例:

m = MODULE_LIST()
m.countModules = countModules
m.names = (MODULE_NAME * countModules)() # create instance of array

我应该如何将空闲行从cpp转换为python?

如果如上所述进行分配,Python将在不再引用内存时释放它,例如当上面的m超出范围时。您可以调用del m来显式取消引用内存。如果m是唯一的引用,它将被释放。

typedef结构到类的转换是否正确?特别是";MODULE_LIST";。

否,CHAR8 name[M_MODNAMELEN_A];是一个数组,因此将类型乘以长度可以得到正确的数组类型:

M_MODNAMELEN_A = 100  # some constant that wasn't defined by OP
class MODULE_NAME(Structure):
_fields_ = ('name',c_char * M_MODNAMELEN_A),

MODULE_LIST有一个16位整数,因此使用正确的16位类型:

class MODULE_LIST(Structure):
_fields_ = (('countModules',c_uint16),
('names',POINTER(MODULE_NAME)))

为了正确调用函数,最佳实践是为函数定义.argtypes.restype,以改进错误检查:

# Assume "int GetCountModules(HANDLE handle, UINT16* pCount)" exists in dll.
dll = CDLL('./somedll')
dll.GetCountModules.argtypes = c_void_p, POINTER(c_uint16)
dll.GetCountModules.restype = c_int
# Make an instance to the output parameter and pass it by reference:
countModules = c_uint16()
ret = dll.GetCountModules(targetHandle, byref(countModules))

最新更新