如何在Dymola中从外部C代码返回含double*的结构体?
问题描述
定义了如下C结构体与函数,编译为静态库后在Dymola中调用时编译成功,但运行提示“无错误指示停止”:
C代码
typedef struct ModelicaExport { double* foo; double* bar; } ModelicaExport; void testExport(double a, double b, void * modelicaExport) { ModelicaExport* output = modelicaExport; double* foo = output->foo; double* bar = output->bar; foo[0] = a; foo[1] = b; bar[0] = a - b; bar[1] = a + b; }
Dymola代码
record recordTest Real foo[3]; Real bar[3]; end recordTest; function testExportC "test calculation through external C code" extends Modelica.Icons.Function; input Real a; input Real b; output recordTest cc; external "C" testExport(a, b, cc) annotation(Include="#include \"myheader.h\"",Library="mylib"); end testExportC;
问题原因与修复方案
核心问题:C结构体与Dymola Record的内存布局不匹配
C中的ModelicaExport结构体存储的是数组指针(double* foo),但Dymola的recordTest直接存储数组元素,两者内存结构完全不同。Dymola传递record时,会把整个数组的连续内存传给外部函数,而不是指针地址,导致C函数里对指针的操作直接访问非法内存,引发崩溃。
修复步骤
修改C结构体,对齐Dymola Record的内存布局
把C结构体改为直接存储固定大小的数组,和Dymola record的定义一致:typedef struct ModelicaExport { double foo[3]; // 和Dymola的foo[3]对应,连续存储3个double double bar[3]; } ModelicaExport;修改C函数逻辑,直接操作结构体数组成员
无需解引用指针,直接访问结构体的数组元素:void testExport(double a, double b, void * modelicaExport) { ModelicaExport* output = (ModelicaExport*)modelicaExport; output->foo[0] = a; output->foo[1] = b; output->foo[2] = 0.0; // 初始化第三个元素,避免未定义行为 output->bar[0] = a - b; output->bar[1] = a + b; output->bar[2] = 0.0; }调整Dymola函数的参数传递方式
Dymola中需要明确传递record的指针(匹配C函数的void*参数),在external调用时添加pointer修饰符:function testExportC "test calculation through external C code" extends Modelica.Icons.Function; input Real a; input Real b; output recordTest cc; external "C" testExport(a, b, pointer(cc)) annotation(Include="#include \"myheader.h\"",Library="mylib"); end testExportC;
额外注意事项
- 确保C结构体的数组大小和Dymola record的数组大小完全一致(此处均为3),避免内存越界。
- 修改C代码后重新编译静态库,在Dymola中重新加载库文件,避免使用旧的编译产物。
内容的提问来源于stack exchange,提问作者MrBellamy
相关产品推荐
相关产品推荐

