How to Get Outputs from ccall

Hi, I’m trying to port some MATLAB code over to Julia that relies on some of MATLAB’s calllib() functions. However, I am confused how I am supposed to get multiple outputs out of Julia’s ccall() function as we are only able to define the type of a single output but are required to type all the inputs, so this tells me that this is not possible.

Here is an example of the issue. A MATLAB call looks like this:

libname = 'refprop';
T = 300.0;
P_rp = 101325;
z = 1;
herr = 32*ones(255);
 [~,~,~,D_rp,Dl,Dv,x,y,q,e,h,s,cv,cp,w,ierr,errTxt] = calllib(libName,'TPFLSHdll', T, P_rp, z, 0, 0, 0, zeros(1,numComponents), zeros(1,numComponents), 0, 0, 0, 0, 0, 0, 0, 0, herr, 255);

In Julia, I do:

T = 300.0;
P_rp = 101325;
z = 1;
# herr = 32*ones(255); # for some reason passing this breaks everything, but that's another problem
D_rp = Cdouble;
Dl = Cdouble;
Dv = Cdouble;
val = ccall((:TPFLSHdll,:REFPRP64),Cdouble,(Cdouble,Cdouble,Cdouble,Cdouble,Cdouble,Cdouble,Ptr{Cdouble},Ptr{Cdouble}, Cdouble, Cdouble, Cdouble, Cdouble, Cdouble, Cdouble, Cdouble, Cdouble, Ptr{Cdouble}, Cdouble),T,P_rp,z,0,0,0,zeros(1),zeros(1),0,0,0,0,0,0,0,0,32*ones(255),255);

And this gives me val = 0.0, and I don’t know how to access the variables such as D_rp. Is this even possible in Julia or do I have to stay in MATLAB?

By the way, the documentation of the TPFLSHdll library with inputs and outputs (?) is on the bottom of document page 124 /pdf page 128 HERE.

Try this

https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Passing-Pointers-for-Modifying-Inputs-1

This looks like a Fortran library, so the following note from the manual here: https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/ applies:

When calling Fortran, all inputs must be passed by pointers to heap- or stack-allocated values, so all type correspondences above should contain an additional Ptr{..} or Ref{..} wrapper around their type specification.

There’s more information about wrapping Fortran subroutines here: https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#When-to-use-T,-Ptr{T}-and-Ref{T}-1

And another related question here: Calling fortran function

Basically, all of your input types in the ccall should be Ref{Cdouble}, Ref{Cint}, etc. The return type must be Cvoid because Fortran subroutines don’t return anything in the sense we’re talking about.

I would suggest starting with a much simpler example to get an idea of what’s going on. If you can write your own Fortran code, start with a subroutine with one argument and make sure you can call it correctly, then try a subroutine with one input and one output. If you can’t, then maybe you can start with a simpler function in the same library, just to get a sense of what’s going on.

2 Likes