我正在尝试使用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))