Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register

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

Re: Return argument for external function

Hi

I just used one value as a dummy example. I actually want to return several values (vectors or matrices).

Thanks for the supplied hints! I will check it out!

P

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

https://specification.modelica.org/mast … ml#records

You cannot pass a record by value.

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...

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.

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?



Edited by: phillipmaree - May-18-20 13:38:19
There are 0 guests and 0 other users also viewing this topic
You are here: