ctypes
предполагает, что аргументы и возвращаемые значения являются 32-разрядными целыми числами (ctypes.c_int
), если не указано иное. В частности, если вы используете 64-битный Python, указатели будут усечены до 32 бит. Первое, что нужно сделать, это объявить аргументы функции и вернуть значения правильно:
mydll.Student_SetId.argtypes = c_void_p,c_int
mydll.Student_SetId.restype = None
mydll.Student_GetId.argtypes = c_void_p,
mydll.Student_GetId.restype = c_int
mydll.School_new.argtypes = ()
mydll.School_new.restype = c_void_p
mydll.School_CreateStudent.argtypes = c_void_p,
mydll.School_CreateStudent.restype = c_void_p
mydll.School_GetStudent.argtypes = c_void_p,
mydll.School_GetStudent.restype = c_void_p
Это также поможет вам отлавливать ошибки, например, School_CreateStudent()
необходимо передать School*
для правильной работы.
Чтобы поймать еще больше ошибок, объявите определенные типы указателей. Вот небольшой класс, который будет отображать его тип и пример:
class Ptr(c_void_p):
def __repr__(self):
cls_name = self.__class__.__name__
if self.value is not None:
return f'{cls_name}({self.value:#x})'
return f'{cls_name}(None)'
class pStudent(Ptr): pass
class pSchool(Ptr): pass
Демо-версия:
>>> p = pSchool()
>>> p
pSchool(None)
Затем объявите аргументы функции и результаты следующим образом:
mydll.Student_SetId.argtypes = pStudent,c_int
mydll.Student_SetId.restype = None
mydll.Student_GetId.argtypes = pStudent,
mydll.Student_GetId.restype = c_int
mydll.School_new.argtypes = ()
mydll.School_new.restype = pSchool
mydll.School_CreateStudent.argtypes = pSchool,
mydll.School_CreateStudent.restype = pStudent
mydll.School_GetStudent.argtypes = pSchool,
mydll.School_GetStudent.restype = pStudent
Теперь везде, где код используется неправильно в Python, должно появиться хорошее сообщение об ошибке.
Как только вы исправите свой код на C ++ и Python, ваш вывод для print(getobj)
будет выглядеть примерно так:
pStudent(0x1b54b89b350)