如何在C++头文件中使用Python ctypes初始化结构变量?

1 投票
2 回答
1669 浏览
提问于 2025-04-16 14:20

我正在尝试在.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 个回答

0

我建议你不要直接从DLL里导出变量。相反,你应该从你的DLL里导出两个函数:一个用来读取这个变量,另一个用来写入这个变量。

0

看起来你把结构的定义和结构的实例搞混了。在头文件中,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

撰写回答