- Index
- » Programming
- » Modelica Language
- » Return argument for external function
Return argument for external function
Return argument for external function
Hi
I try to pass back a struct by reference from a return Extern C function call in OpenModelica.
I have defined a struct in C, and a Record in OM with similar fields, however it seem I still miss some detail in how to get it to work.
I very crude idea of what I am currently doing is:
Code:
record In
Real value;
end In;
record Out
Real value;
end Out;
function extern_func
input In in
output Out out
external "C" out = sample_solver( in )
end extern_func
Input in;
Output out;
equation
in.val = 1;
out = sample_solver( in )
Assumptions:
I assume I pass struct by reference as void* from C.
Thanks for any consideration or pointers!
Phillip
Re: Return argument for external function
Why do you want to use records if you only have one value?
Anyhow, you might hit this bug:
https://trac.openmodelica.org/OpenModelica/ticket/5774
pointed out by (you also have an example there):
https://www.openmodelica.org/forum/defa … c-function
- adrpo
- 885 Posts
Re: Return argument for external function
It seems I got it to work apart from a pesky warning about passing of pointer mismatch.
I was wondering if it could be due to poor implementation maybe?
My Extern C function calls are defines as follows:
Code:
function sample_model
input Solver.PhotovoltaicSolver solver_ptr;
input Solver.Archive.PV.Arg arg;
output Solver.Archive.PV.Res res;
external "C" sample_solver(solver_ptr, arg, res );
annotation(
Library = "photovoltaic",
LibraryDirectory = "modelica://components/Resources/Library");
end sample_model;
where the compiles generates the following warning:
Code:
Components.Photovoltaic_functions.c:20:44: warning: incompatible pointer types passing 'Components_Solver_Archive_PV_Res *' to parameter of type 'Components_Solver_Archive_PV_Res **' [-Wincompatible-pointer-types]
sample_solver(_solver_ptr_ext, _arg_ext, &_res_ext);
^~~~~~~~~
./Components.Photovoltaic_functions.h:112:138: note: passing argument to parameter here
extern void sample_solver(void * /*_solver_ptr*/, Components_Solver_Archive_PV_Arg* /*_arg*/, Components_Solver_Archive_PV_Res** /*_res*/);
^
Could be that I pass res as an output which is also an input to sample_solver which cause the referencing warning?
Thanks for thoughts!
Re: Return argument for external function
Hi
It seems to me that if one passes a record as argument to external C function with the aim of returning some data in this record, then one ends up with the incompatible pointer warning (see previous post).
I guess it must be due to declaring the record as an output in the function declaration, but then pass it as an input to the external C function?
To get rid of this warning, one can pass the record as input argument to external C function, and then the external C function can return a reference to this record which is assigned to some output defined record variable. See below code snippet (does not generate the incompatible pointer warning):
Code:
function sample_model
input Solver.PhotovoltaicSolver solver_ptr;
input Solver.Archive.PV.Arg arg;
input Solver.Archive.PV.Res res0;
output Solver.Archive.PV.Res res;
external "C" res = sample_solver(solver_ptr, arg, res0 );
annotation(
Library = "photovoltaic",
LibraryDirectory = "modelica://components/Resources/Library");
end sample_model;
This doesn't see seem very eloquent!
If there are other better methods to obtaining the same result, then I would be happy to receive some suggestions in how to implement this.
Thanks,
Phillip
Re: Return argument for external function
- sjoelund.se
- 1700 Posts
Re: Return argument for external function
Never mind, I'm stupid. It says further down if it's lhs, it is passed by value instead of reference...
- sjoelund.se
- 1700 Posts
Re: Return argument for external function
So your issue is that code such as the following should work, but does not - right?
Code:
model M
record R
Real x,y;
end R;
function sample_model
input R r;
output R res;
external "C" sample_solver(r, res);
end sample_model;
R r = sample_model(R(time,time));
end M;
If so it should be possible to fix it.
- sjoelund.se
- 1700 Posts
Re: Return argument for external function
In your proposed example, it does work, however, it generates incompatible pointer warnings which suggests I might be doing something wrong.
And as comment on your previous comments, I do pass my record by reference (at least from the C side). My C function is defined as:
Code:
void* sample_solver( void* solve_vptr, void* arg_ptr, void* res_ptr )
{
return ((PhotoVoltaicC*)solve_vptr)->sample( (PhotoVoltaicC::ArgSt*)arg_ptr, (PhotoVoltaicC::ResSt*)res_ptr );
}
which match up with the Modelica code as:
Code:
function sample_model
input Solver.PhotovoltaicSolver solver_ptr;
input Solver.Archive.PV.Arg arg;
input Solver.Archive.PV.Res res0;
output Solver.Archive.PV.Res res;
external "C" res = sample_solver(solver_ptr, arg, res0 );
annotation(
Library = "photovoltaic",
LibraryDirectory = "modelica://components/Resources/Library");
end sample_model;
Correct me if I am wrong, but I do pass the record by reference as I did above? Or does Modelica have some syntax to pass a record by reference?
- Index
- » Programming
- » Modelica Language
- » Return argument for external function