- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Let me recast your snippet so that it is a little more standard conforming, and works...
[fortran]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[/fortran]
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:
[cpp]float addnums(float *val1, float *val2);[/cpp]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.
[plain]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[/plain]To use:
loadlibrary('YourDLLName.dll', @prototypes);
The floatPtr is the equivalent of "pass a float (REAL(4)) by reference".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page