- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » Return array from external function
Return array from external function
Return array from external function
Hello
I would like to ask if there is a way how to pass more then one return value from external C function. Is it possible? I know that in C i have to send just refference, but i am not quite sure how it works in/with openmodelica. Does someone have an example ? Thanks
Re: Return array from external function
See in the Modelica Specification:
https://modelica.org/documents/Modelica … ision1.pdf
12.9.1.2 Arrays
- adrpo
- 885 Posts
Re: Return array from external function
So basically there is written, that arrays are not possible. But i found there that structures / records are possible. But there is so little documentation about it. Can you please help me ? There is a piece of code which I have in modelica
1 class
Code:
segway_vars vars;
record segway_vars
Real phi(start = 0);
Real speedR(start = 0);
Real speedL(start = 0);
Real posR(start = 0);
Real posL(start = 0);
end segway_vars;
/// record is defined and initialised
// now there is a calling to external function
function Get_outp
input Real u1, u2;
input Modelica.SIunits.Time simTime;
/*input Real time;*/
output segway_vars mystruct;
external mystruct = ComunicationInterface(u1, u2, simTime) annotation(Library = "libgetref.o", Include = "#include \"Handle_data.h\"");
end Get_outp;
//just equation part
vars = Get_outp(u1, u2, time);
This is what i have done in openmodelica and compiling gets before calling external function(when i run it without libraries for my functions) so it should be ok i think.
The question is about C part(where i think problem lies). In documentation I have found out in 12.9.1.3 Records that Records are passed by reference (i.e. a pointer to the record is being passed).
So i created global structure in my header file
Code:
typedef struct segway_vars {
double phi;
double speedR;
double speedL;
double posR;
double posL;
} seg_output;
seg_output * seg_output_p;
double Get_reference_signal(double refval, int shkey);
seg_output *ComunicationInterface(double u1,double u2, double timesim);
double initTimetck(double);
And then I initialise memory fot it in function initTimettck which run only once on initial by
Code:
seg_output_p = malloc (sizeof (struct segway_vars));
And then I use it like this in function
Code:
seg_output *ComunicationInterface(double u1, double u2, double timesim) {
//some not important code and then this
seg_output_p->phi=AT;
seg_output_p->posL=0.2;
seg_output_p->posR=0.3;
seg_output_p->speedL=0.4;
seg_output_p->speedR=0.5;
//(fixed values are just for testing for now)
return seg_output_p;
}
Question is what have I done wrong? Complilation of simulation says:
Code:
Error: Error building simulator. Build log: clang -fPIC -O0 -march=native -g -I"/usr/include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -c -o Segway.simulation.o Segway.simulation.c
clang -fPIC -O0 -march=native -g -I"/usr/include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -c -o Segway.simulation_functions.o Segway.simulation_functions.c
Segway.simulation_functions.c:21:17: error: assigning to 'Segway_comunication__helper_segway__vars' (aka 'struct Segway_comunication__helper_segway__vars_s') from incompatible type 'seg_output *' (aka 'struct segway_vars *')
_mystruct_ext = ComunicationInterface(_u1_ext, _u2_ext, _simTime_ext);
^ ~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Or do you have any working example please? Thank you
Re: Return array from external function
Because records are passed by reference, you need to pass it as an input to the function and not return in.
- sjoelund.se
- 1700 Posts
Re: Return array from external function
@bumino: you can pass arrays as given in the specification. You need to pass them as input in the external functions (C references).
- adrpo
- 885 Posts
Re: Return array from external function
To: sjoelund.se
Thank you I now understand. I thought that meaning of passing the reference was about returning pointer. Now I understand that it is about changing the structure in function via passed reference I will try to do it this way.
To adrpo
I just needed to return 5 vals from my function. ( I dont exactly now if u meant that I should use same model as sjoelund.se proposed with structures but these structures I like more:) because it is defined better by var names:) )
Thank you both for help Have a nice week.
Re: Return array from external function
I looked into it more and a new problem arised. How should I declare this input structure in my code ? Which type it should be? I tried to build exactly same structure as was pointed out in documentation, but it does not work (in structure/record mapping there is really too few written about it)
Error: Error building simulator. Build log: clang -fPIC -O0 -march=native -g -I"/usr/include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -c -o Segway.simulation.o Segway.simulation.c
clang -fPIC -O0 -march=native -g -I"/usr/include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -c -o Segway.simulation_functions.o Segway.simulation_functions.c
Segway.simulation_functions.c:21:45: error: passing 'Segway_comunication__helper_segway__vars' (aka 'struct Segway_comunication__helper_segway__vars_s') to parameter of incompatible type 'struct segway_vars *'
_goon_ext = ComunicationInterface(_u_ext, _inpstruct_ext, _simTime_ext);
^~~~~~~~~~~~~~
./Handle_data.h:18:56: note: passing argument to parameter 'seg_output_p' here
int ComunicationInterface(double u,struct segway_vars *seg_output_p, double timesim);
in C code
Code:
struct segway_vars {
double phi;
double speedR;
double speedL;
double posR;
double posL;
};
in OM
Code:
record segway_vars
Real phi(start = 0);
Real speedR(start = 0);
Real speedL(start = 0);
Real posR(start = 0);
Real posL(start = 0);
end segway_vars;
There is really not an example? It would have explained a lot
Re: Return array from external function
I also tried it with arrays
I can read from array, but when I try to write to array segmentation fault occurs
Also documenations says that there is size_t with length about array but there is not.
Found the core of the problem
one have to call it like this :::
function foo
input Real a[:,:,:];
output Real x;
external;
end foo;
and not
function foo2
input Real a[:,:,:];
output Real x;
external x=foo(a);
end foo2;
- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » Return array from external function