Search code examples
cstructexterndymola

How to return a struct of double* in dymola from an external C code


This question is similar to this one : Is it possible to return multiple values from an external file to Dymola? but somehow, it could not help me.

I have the following C structure:

typedef struct ModelicaExport
{
    double* foo;
    double* bar;
} ModelicaExport;

and the following test function in C.

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;
}

The structure and function behaves normally in C, no issues here. I can export the function as a static library using Visual Studio Build Tools 2019. No issues here either.

The problem arises when I call this function is Dymola. I recreated the "structure" in Dymola as a record ( as indicated here https://mbe.modelica.university/behavior/functions/external/ )

record recordTest
  Real foo[3];
  Real bar[3];
end recordTest;

Then I created the function is dymola to call my external C function:

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;

I am confident the annotation with the header and library is correct since I tried it on even simpler function and everything works well. However testExportC does not work. It compiles fine, I get a message from dymola saying compilation is successful but then it "stopped without error indication" according to Dymola. What could I be missing ? I am using Dymola 2023x with Visual Studio Build Tools 2019 also.


Solution

  • The external C interface in Modelica is intended for returning "values", and only scalars in records can be handled - specifically arrays as in modelicaExport are not supported, https://specification.modelica.org/master/functions.html#records

    This is a recent change and the old link you use hasn't been updated.

    The reason for forbidding arrays is that in practice arrays are often variable-length and that would create a mess. In particular in C the following structs:

    typedef struct ModelicaExport
    {
        double* foo;
        double* bar;
    } ModelicaExport;
    
    struct ModelicaExport2 {
      double foo[3];
      double bar[3];
    }
    

    are completely different, and not compatible.

    You will either have to re-think the original issue (it might be a X-Y problem), or write a C-wrapper for testExport.