Call an Intel Fortran DLL from MATLAB

Call an Intel Fortran DLL from MATLAB

I need to call a DLL written in IVF V11.x from MATLAB. I dont know how go about solving this problem I was able to solve the problem using the MEX method but I am interested knowing how to call a Fortran compiled Dll in MatLab. For now all I need to is add two numbers and return the output.

[Source2.f90]
real*4 function addnums(val1,val2)
!dec$ attributes dllexport,alias : "addnums" :: addnums
real*4 val1,val2
fortomatreal=val1+val2
end function

How do I generate the addnum.h file from the above code? I dont know c at all.

I found an example of MatLab can I adapt for windows os?

[example.m]
if libisloaded('lib')~=1
if ispc
loadlibrary endecdll.dll endecdll.h alias lib
else % lunix
loadlibrary libendecdll.so endecdll.h alias lib % \\-> for linux
end;
%libfunctions lib libfunctions lib \\-full
%calllib('lib','fortomatint',5,5)
%calllib('lib','fortomatreal',5.4,3.7)
if libisloaded('lib')==1
unloadlibrary lib;
end;

any help would be appreciated

9 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

These questions are more appropriately asked in a Mathworks/Matlab forum.

Let me recast your snippet so that it is a little more standard conforming, and works...

FUNCTION addnums(val1,val2) BIND(C, NAME='addnums')
!dec$ attributes dllexport :: addnums
  USE ISO_C_BINDING, ONLY: C_FLOAT
  IMPLICIT NONE
  REAL(C_FLOAT), INTENT(IN) :: val1, val2
  REAL(C_FLOAT) :: addnums
  addnums = val1 + val2
END FUNCTION

C_FLOAT is kind 4 with Intel Fortran. Note the arguments val1 and val2 do not have the VALUE attribute - the arguments will be passed by reference.

The equivalent C header for this is:

float addnums(float *val1, float *val2);

The * before the parameters in the C declaration means that the arguments are passed by reference (pointers).

You can place that line in a plain text header file (.h) file, and then use that header file as the hfile argument to the matlab loadlibrary function.

Alternatively you can use what is called a prototype function, and pass the handle to the function as the hfile argument. The prototype function returns a matlab structure that describes each call in the library.

function [methodinfo,structs,enuminfo,ThunkLibName]=prototypes

  % Platform specific.  This is for 32 bit Matlab with 32 bit Intel fortran.
  default_integer = 'int32';
  default_integer_ptr = 'int32ptr';

  ival = {cell(1,1)};
  structs = [];
  enuminfo = [];
  fcnNum = 1;
  fcns=struct('name',ival,'calltype',ival,'LHS',ival,'RHS',ival,'alias',ival);
  ThunkLibName=[];
  
  fcns.name{fcnNum}='addnums'; 
  fcns.calltype{fcnNum}='cdecl';
  fcns.LHS{fcnNum}=['float'];
  fcns.RHS{fcnNum}={'floatPtr', 'floatPtr'};
  fcnNum = fcnNum + 1;  
end

To use:

loadlibrary('YourDLLName.dll', @prototypes);

The floatPtr is the equivalent of "pass a float (REAL(4)) by reference".

[addnums.f90]

FUNCTION
addnums(val1,val2) BIND(C, NAME='addnums')

!dec$
attributes dllexport :: addnums

USE ISO_C_BINDING, ONLY: C_FLOAT

IMPLICIT NONE

REAL(C_FLOAT), INTENT(IN) :: val1, val2

REAL(C_FLOAT) :: addnums

addnums = val1 + val2

END
FUNCTION

Compiled
using Fortran command line for x64

ifort
/dll addnums.f90

[addnums.h]

float
addnums(float *val1, float *val2);

[prototypes.m]

function
[methodinfo,structs,enuminfo,ThunkLibName]=prototypes

% Platform specific. This is for 32 bit Matlab with 32 bit Intel
fortran.

default_integer = 'int32';

default_integer_ptr = 'int32ptr';

ival = {cell(1,1)};

structs = [];

enuminfo = [];

fcnNum = 1;

fcns=struct('name',ival,'calltype',ival,'LHS',ival,'RHS',ival,'alias',ival);

ThunkLibName=[];

fcns.name{fcnNum}='addnums';

fcns.calltype{fcnNum}='cdecl';

fcns.LHS{fcnNum}=['float'];

fcns.RHS{fcnNum}={'floatPtr', 'floatPtr'};

fcnNum = fcnNum + 1;

end

What changes are needed to run this on Win XP 64B and Matlab
R2011a?

Quoting bjdesa

What changes are needed to run this on Win XP 64B and Matlab
R2011a?


For that specific exanple I don't believe you need to make any changes.

Interfacing with Fortran

I managed to solve interface with Fortran using the "mexfile method"

The problem is not everyone has a Fortran compiler in my office and they have different MatLab version too.

Therefore I am trying to figure out how to solve it using the loadlibrary method

Computer configuration: OS Win XP 32b and MatLab 2010b 32b

[addnums.f90]

FUNCTION addnums(val1,val2) BIND(C, NAME='addnums')

!dec$ attributes dllexport :: addnums

USE ISO_C_BINDING, ONLY: C_FLOAT

IMPLICIT NONE

REAL(C_FLOAT), INTENT(IN) :: val1, val2

REAL(C_FLOAT) :: addnums

addnums = val1 + val2

END FUNCTION

I compiled using Intel Fortran 11.x

ifort /dll addnums.f90

[addnums.h]

float addnums(float *val1, float *val2);

Now in MatLab the following worked

%loadlibrary('addnums','addnums.h','mfilename','addnums1.m')

The Matlab generated the file 'addnums1.m'

I typed the following and got the following response:

>> loadlibrary('addnums','addnums.h','mfilename','addnums1.m')

>> addnums1(100.0,30.0)

??? Error using ==> addnums1

Too many input arguments.

>> addnums1

ans =

name: {'addnums'}

calltype: {'cdecl'}

LHS: {'single'}

RHS: {{1x2 cell}}

alias: {1x0 cell}

Interfacing with Fortran

I managed to solve interface with Fortran using the "mexfile method"

The problem is not everyone has a Fortran compiler in my office and they have different MatLab version too.

Therefore I am trying to figure out how to solve it using the loadlibrary method

Computer configuration: OS Win XP 32b and MatLab 2010b 32b

[addnums.f90]

FUNCTION addnums(val1,val2) BIND(C, NAME='addnums')

!dec$ attributes dllexport :: addnums

USE ISO_C_BINDING, ONLY: C_FLOAT

IMPLICIT NONE

REAL(C_FLOAT), INTENT(IN) :: val1, val2

REAL(C_FLOAT) :: addnums

addnums = val1 + val2

END FUNCTION

I compiled using Intel Fortran 11.x

ifort /dll addnums.f90

[addnums.h]

float addnums(float *val1, float *val2);

Now in MatLab the following worked

%loadlibrary('addnums','addnums.h','mfilename','addnums1.m')

The Matlab generated the file 'addnums1.m'

I typed the following and got the following response:

>> loadlibrary('addnums','addnums.h','mfilename','addnums1.m')

>> addnums1(100.0,30.0)

??? Error using ==> addnums1

Too many input arguments.

>> addnums1

ans =

name: {'addnums'}

calltype: {'cdecl'}

LHS: {'single'}

RHS: {{1x2 cell}}

alias: {1x0 cell}

What did I am do wrong?

The addnums1.m file that you generated is just the equivalent of the prototype function referred to in post #2.

To call the function in the library you use calllib.

calllib('addnums', 'addnums', 1.0, 2.0)

See the matlab help for loadlibrary and calllib for more information.

[AAA.f90]
SUBROUTINE AAA(a0,Pltout1,Ipltbm1,Npltbm1)
&BIND(C, NAME='AAA')
!dec$ attributes dllexport :: AAA
USE ISO_C_BINDING, ONLY: C_DOUBLE, C_INT
IMPLICIT NONE
REAL(C_DOUBLE), INTENT(IN) :: a0(10)
REAL(C_DOUBLE), INTENT(OUT) :: Pltout1(500,20)
INTEGER(C_INT), INTENT(OUT) :: Ipltbm1, Npltbm1

[AAA.h]
void AAA(double *a0[10], double *nPltout1[500][20], int *Ipltbm1, int *Npltbm1);

>> loadlibrary('AAA','AAA.h')
Warning: The library name case did not match the file name.
The library will be named "AAA".
> In loadlibrary at 174
??? Error using ==> loadlibrary at 477
There was an error loading the library "Z:\MatLab\Project2\AAA.dll"
The specified module could not be found.

Caused by:
Error using ==> loaddefinedlibrary
The specified module could not be found.

What am I doing wrong?

Leave a Comment

Please sign in to add a comment. Not a member? Join today