使用Python ctypes调用Simulink生成C代码初始化函数遇问题求助
问题排查与修复建议
1. 函数参数类型不匹配(核心问题)
C中model_initialize的第一个参数是指针类型RT_MODEL_model_T *const,但你的Python代码直接传递了结构体实例model_M_(值传递),这会导致参数类型完全不匹配。
修复:
传递你已定义的指针变量model_M,而非结构体实例:
# 修正初始化调用 initialize(model_M, byref(model_U_ref), byref(model_Y_measure))
2. 结构体类型名必须严格匹配
检查C代码中tag_RTM_Model_NAME_T的typedef别名是否为RT_MODEL_model_T,必须保证C与Python的结构体类型名完全一致:
// C代码中必须补充该typedef,否则RT_MODEL_model_T类型不存在 typedef struct tag_RTM_Model_NAME_T RT_MODEL_model_T;
如果C中实际typedef名为RT_MODEL_NAME_T(对应ert_main里的命名),Python的结构体类名也要同步改为RT_MODEL_NAME_T。
3. boolean_T类型映射需确认
Simulink的boolean_T在不同编译环境下定义不同:
- 多数场景是
typedef unsigned char boolean_T;,此时Python用c_ubyte正确; - 若为
typedef int boolean_T;,则Python需改为c_int。
验证方法:
在C代码中添加打印语句确认类型大小:
printf("boolean_T size: %zu\n", sizeof(boolean_T));
输出为4则用c_int,输出为1则用c_ubyte。
4. 显式指定函数参数类型与返回值
ctypes默认自动推导类型易出错,显式指定可避免参数传递混乱:
# 显式设置函数参数类型和返回值 initialize.argtypes = [POINTER(RT_MODEL_model_T), POINTER(c_double), POINTER(c_double)] initialize.restype = None # 根据实际step/terminate函数参数补充 step.argtypes = [POINTER(RT_MODEL_model_T)] step.restype = None terminate.argtypes = [POINTER(RT_MODEL_model_T)] terminate.restype = None
5. 结构体对齐规则一致性
如果C代码使用了特殊对齐(如#pragma pack(1)),Python结构体需同步设置:
class DW_model_T(Structure): _pack_ = 1 # 与C代码的对齐值保持一致 _fields_ = [("state1_DSTATE", c_double), ("state2_DSTATE", c_double), ("DiscreteTimeIntegrator1_DSTATE", c_double), ("DiscreteTimeIntegrator_LOAD", c_ubyte), ("G1_PreviousInput", c_ubyte)] # 根据boolean_T实际类型调整
6. 确认库中函数的正确性
- 用
nm ./test.so | grep model_initialize检查函数是否存在,若为C++编译,必须给函数加extern "C"避免名字混淆:
// C++代码中必须添加extern "C" extern "C" { void model_initialize(RT_MODEL_model_T *const model_M, real_T *model_U_reference, real_T *model_Y_measure); void model_step(RT_MODEL_model_T *const model_M); void model_terminate(RT_MODEL_model_T *const model_M); }
内容的提问来源于stack exchange,提问作者Imad El Bouhali
相关产品推荐
相关产品推荐

