如何在C++头文件中使用Python ctypes初始化结构变量?
我正在尝试在.h头文件中使用Python的ctypes来初始化一个叫做ExternalInputs_add_two
的结构体。这个头文件是:
typedef struct {
int32_T Input; /* '<Root>/Input' */
int32_T Input1; /* '<Root>/Input1' */
} ExternalInputs_add_two;
我需要初始化这个结构体,因为这个成员声明需要用到结构体的值作为输入:
extern ExternalInputs_add_two add_two_U;
用什么ctypes函数可以初始化这个结构体呢?到目前为止,我的Python代码是:
class ModelOutput(Structure):
_fields_ = [("Output", c_int)]
class ModelInput(Structure):
_fields_ = [("Input", c_int),
("Input1", c_int)]
#define the functions
initiateModel = cdll.add_two_win32.add_two_initialize
stepModel = cdll.add_two_win32.add_two_step
terminateModel = cdll.add_two_win32.add_two_terminate
#define the pointers to the functions
initiateModel.restype = c_void_p
stepModel.restype = c_void_p
terminateModel.restype = c_void_p
#initialize the model with value of 1
print "\n\nInitialize"
errMsg = initiateModel(1)
print "initateModel reports:", errMsg
#Set the input
test_input = ModelInput(1,2)
input_ptr = pointer(test_input)
#This probably doesn't work since ExternalInputs_add_two is a structure, not a function.
cdll.add_two_win32.ExternalInputs_add_two = input_ptr
#Get the output pointer from add_two_U
output = POINTER(ModelOutput)
results = output.in_dll(cdll.add_two_win32,"add_two_U")
print "got results", results.Output
我昨天问过一个问题,如何获取成员add_two_U
的输出。David很友好地回答了这个问题(使用in_dll
函数)。
我在ctypes的文档和网上搜索过,想找一个例子或者函数来用ctypes设置一个结构体,但到现在为止还没找到。
谢谢你的帮助。
谢谢你的帮助和回答。不幸的是,这种方式设置输入结构体并不奏效。我忘了提到,有一个Matlab脚本是用来调用这个dll的,并且它可以正常工作。我正在尝试转换成Python。为了初始化结构体ExternalInputs_add_two
,Matlab使用了以下语句:
sm.Input = 1
sm.Input1 = 2
sp = libpointer('ExternalInputs_add_two', sm)
然后调用函数add_two_U
:
sp = calllib('add_two_win32', 'add_two_U')
sp.value
get(sp, 'Value')
sp.Value.Input = 3
sp.Value.Input1 = 2
如果我去掉初始化ExternalInputs_add_two
结构体的Matlab语句,就会出现错误。
用Python的ctypes,初始化这个结构体的对应方法是什么呢?抱歉如果我让你觉得烦。
2 个回答
我建议你不要直接从DLL里导出变量。相反,你应该从你的DLL里导出两个函数:一个用来读取这个变量,另一个用来写入这个变量。
看起来你把结构的定义和结构的实例搞混了。在头文件中,ExternalInputs_add_two
是一个 类型,而 add_two_U
是一个 实例。DLL(动态链接库)只会导出类型的实例,而不是类型本身。所以你在 Python 代码中的这一行是没有意义的:
cdll.add_two_win32.ExternalInputs_add_two = input_ptr
你可能想要做的是修改名为 add_two_U
的 实例,也就是 ExternalInputs_add_two
的那个实例。要做到这一点,你可以按照 David 之前的回答,使用 in_dll
函数:
PModelInput= POINTER(ModelInput)
padd_two_U = PModelInput.in_dll(cdll.add_two_win32, "add_two_U")
# Now modify the contents of the "add_two_U" variable
padd_two_U.Input = 1
padd_two_U.Input2 = 2