You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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函数里对指针的操作直接访问非法内存,引发崩溃。

修复步骤

  1. 修改C结构体,对齐Dymola Record的内存布局
    把C结构体改为直接存储固定大小的数组,和Dymola record的定义一致:

    typedef struct ModelicaExport
    {
        double foo[3]; // 和Dymola的foo[3]对应,连续存储3个double
        double bar[3];
    } ModelicaExport;
    
  2. 修改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;
    }
    
  3. 调整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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:33:17