Типы файлов Python как работать с malloc/бесплатно?

#python #c #ctypes

Вопрос:

Я пытаюсь преобразовать файл .cpp в .py, используя библиотеку ctypes.

Некоторые базовые операции работают, но я испытываю трудности при использовании структур typedef, а также malloc/free.

Вот что у меня есть:

модуль.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, amp;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?
 

Python работает нормально до строки «modList.names=».. Там я попробовал несколько вещей (например: modList.names = (ИМЯ_МОДУЛЯ)count_modules.value * sizeof(ИМЯ_МОДУЛЯ ())), но все мои попытки не увенчались успехом.

Как мне перевести строку malloc с cpp на python?

Как мне перевести свободную строку с cpp на python?

Являются ли переводы структуры typedef в класс правильными? Особенно один из «MODULE_LIST».

Ответ №1:

Как мне перевести строку malloc с cpp на python?

Обычно библиотека DLL, которая возвращает что-то вроде MODULE_LIST, выполняет за вас 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))