|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Moredom
Joined: 12 Dec 2006 Posts: 5 Location: Germany, Harz-Mountains
|
Posted: Sat Dec 16, 2006 4:33 pm Post subject: Access to MatLab generated .dll using Fortran (ftn95) |
|
|
Hello Everyone!
I'm trying to access MatLab-Functions from an MatLab generated .dll-file.
I discovered an example program, which now works with Digital Fortran, but not with ftn95, which I have to use now.
Since I'm not a very experienced fortran-programmer, I need some help.
If you can help me in any way or point me to documentation, I would be very pleased.
Code: | program test
use kernel32
IMPLICIT NONE
INTERFACE
SUBROUTINE matlabinc(nlhs,plhs, nrhs,prhs)
integer*4 :: nlhs,nrhs
integer*4 :: plhs,prhs
!DEC$ ATTRIBUTES C, DLLIMPORT :: matlabinc
!DEC$ ATTRIBUTES VALUE :: nlhs,nrhs
!DEC$ ATTRIBUTES REFERENCE :: plhs,prhs
END SUBROUTINE
SUBROUTINE matlibInitialize()
!DEC$ ATTRIBUTES C, DLLIMPORT :: matlibInitialize
END SUBROUTINE
SUBROUTINE matlibTerminate()
!DEC$ ATTRIBUTES C, DLLIMPORT :: matlibTerminate
END SUBROUTINE
END INTERFACE
! This part only required for our own Matlab routine, not the mx* routines
integer :: p_matlib_dummy, p_libmx_dummy
logical :: status
! matlib.dll
pointer (p_matlib,p_matlib_dummy)
pointer (pr1_matlib,matlibInitialize)
pointer (pr2_matlib,matlabinc)
pointer (pr3_matlib,matlibTerminate)
! Declare all mx* routines we call
INTEGER*4 :: mxGetData !
INTEGER*4 :: mxGetNumberOfElements !
INTEGER*4 :: mxCreateScalarDouble !
INTEGER*4 :: mxCreateNumericMatrix !
INTEGER*4 :: mxClassIDFromClassName !
real*8 :: a(4) ! What I store in Matlab mx array
real*8 :: b(4) ! What I read out of Matlab mx array
integer*4 :: a_mx_p ! Pointer to mx array for a
integer*4 :: a_dx_p ! Pointer to data in mx array for a
integer*4 :: b_mx_p ! Pointer to mx array for b
integer*4 :: b_dx_p ! Pointer to data in mx array for b
integer*4 :: na ! Number of entries in a
integer*4 :: nb ! Number of entries in b
p_matlib = loadlibrary("matlib.dll"C)
pr1_matlib = getprocaddress(p_matlib, "_matlibInitialize"C)
pr2_matlib = getprocaddress(p_matlib, "_mlxMatlabinc"C)
pr3_matlib = getprocaddress(p_matlib, "_matlibTerminate"C)
! Initialise interface to our Matlab routine
! (this initialisation routine is automatically created by Matlab during compilation)
call matlibInitialize()
a(1) = 1.0
a(2) = 2.0
a(3) = 3.0
a(4) = 5.0
a_mx_p = mxCreateNumericMatrix(4, 1, mxClassIDFromClassName('double'), 0)
a_dx_p = mxGetData(a_mx_p)
call mxCopyReal8ToPtr(a, a_dx_p, 4)
type *, a
call matlabinc(1,b_mx_p, 1,a_mx_p)
b_dx_p = mxGetData(b_mx_p)
call mxCopyPtrToReal8(b_dx_p, b, 4)
type *, b
call mxDestroyArray(a_mx_p)
call mxDestroyArray(b_mx_p)
call matlibTerminate()
end
|
This is the corresponding MatLab code:
Code: | function b = matlabinc(a)
% Increment given argument a and return result b to caller, displaying both on screen as well
disp(a)
b = a + 1;
disp(b)
|
Many thanks in advance for any help in that matter.
Benjamin Zimmermann
Edit: I messed up the Code, now it is working _________________ 42
Last edited by Moredom on Mon Dec 18, 2006 4:06 pm; edited 1 time in total |
|
Back to top |
|
|
DrTip
Joined: 01 Aug 2006 Posts: 74 Location: Manchester
|
Posted: Sat Dec 16, 2006 9:38 pm Post subject: |
|
|
Hi Benjamin
I (at least) would need more info to give any help. What are the error messages when you attempt to compile the program ?
Although I am very familiar with the two languaes I have no experience of interfacing them, but I can probably give some pointers with a few error messages.
A couple of tips when interfacing with fortran
since this works with digital fortran (which used to be called compaq fortran can I suggest first you try compiling with the code with
/CVF_EXTERNAL switch
as this is what thise switch is for.
As a general rule nam all subroutine and functions Upper case names
other wise you have to set up aliases which is an extra thing to worry about. Fortran is not case sensitive. this might be the problem here maybe ?
without more info I can't really say any more one last thing is make sure all the dll's the ftn95 code calls are visible ie on the path of the executable
Carl |
|
Back to top |
|
|
Moredom
Joined: 12 Dec 2006 Posts: 5 Location: Germany, Harz-Mountains
|
Posted: Mon Dec 18, 2006 4:19 pm Post subject: |
|
|
Hi Carl!
First of all, there is no kernel32 module in ftn95, at least I do not have it (=
So there are no routines as 'LOADLIBRARY' and 'GETPROCADDRESS'.
As I read a little bit about 'C_EXTERNAL' and since I know, my functions in the dll are cdecl, I am thinking about trying a little bit around with those.
As I said, that I'm quite new with Fortran, I'll probably need some sample code. (I found some before, so I will try to get that code-snippet again).
Greetings,
Benjamin.
P.S. If you want/can compile the code yourself, I would send you the other necessary files with mail. _________________ 42 |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7942 Location: Salford, UK
|
Posted: Tue Dec 19, 2006 9:36 am Post subject: |
|
|
Benjamin
There are two issues here a) using MATLAB and b) accessing a third party STDCALL Fortran library (if that is what it is). The main documentation for (a) is in the knowledge base of this forum. For (b) you need to look in FTN95.chm.
Again for (b) the usual route is to use the FTN95 compiler switch /IMPORT_LIB <dll_name>. Current versions of FTN95 do not implement /CVF_EXTERNAL.
You also need to know that the comment embedded DEC directives !DEC$ ATTRIBUTES... are ignored by FTN95. Now I come to look at them, they suggest to me that the library is C rather than Fortran. The latest version for MATLAB (from 6.5 I think) uses STDCALL so perhaps the DLL is a C library using the STDCALL protocol. In which case /IMPORT_LIB may not work.
You can certainly get at kernel32. SLINK will scan this library automatically. In your code you can either include windows.ins or use mswin (you may need to check the detail here).
My main advice would be to tackle (a) and (b) separately first of all. That is (a) get MATLAB working without the DLL and (b) access the DLL without using MATLAB. Then you will have the expertise to bring them together. |
|
Back to top |
|
|
Moredom
Joined: 12 Dec 2006 Posts: 5 Location: Germany, Harz-Mountains
|
Posted: Tue Dec 19, 2006 10:24 am Post subject: |
|
|
Hi Paul!
I did some more work of that yesterday.
First of all, the MatLab dll's are CDECL http://www.mathworks.com/support/solutions/data/1-1ZVAO5.html?product=CO&solution=1-1ZVAO5
So I tried a little sample program with C_EXTERNAL (I already read a little bit in kbase and ftn95.chm).
This is what I tried:
Code: | program test
! Declaring external functions
C_EXTERNAL matlibInitialize 'matlibInitialize'
C_EXTERNAL matlibTerminate 'matlibTerminate'
C_EXTERNAL matlabinc 'matlabinc' (val, ref, val, ref)
! Declaring variables for local functions
real*8 :: a(4) ! What I store in Matlab mx array
real*8 :: b(4) ! What I read out of Matlab mx array
integer*4 :: a_mx_p ! Pointer to mx array for a
integer*4 :: a_dx_p ! Pointer to data in mx array for a
integer*4 :: b_mx_p ! Pointer to mx array for b
integer*4 :: b_dx_p ! Pointer to data in mx array for b
integer*4 :: na ! Number of entries in a
integer*4 :: nb ! Number of entries in b
! Declare all mx* routines we call
C_EXTERNAL mxCreateNumericMatrix 'mxCreateNumericMatrix' (val, val, val, val) : INTEGER*4
! Can't find following in .dll's:
! C_EXTERNAL mxClassIDFromClassName 'mxClassIDFromClassName' (string) : INTEGER*4
! Workaround: 'double':6, 'int32':12, 'int16':10
C_EXTERNAL mxGetData 'mxGetData' (ref) : INTEGER*4
C_EXTERNAL mxDestroyArray 'mxDestroyArray' (ref)
! INTEGER*4 :: mxGetData !
! INTEGER*4 :: mxGetNumberOfElements !
! INTEGER*4 :: mxCreateScalarDouble !
! INTEGER*4 :: mxCreateNumericMatrix !
! INTEGER*4 :: mxClassIDFromClassName !
! Initialise interface to our Matlab routine
call matlibInitialize()
a(1) = 1.0
a(2) = 2.0
a(3) = 3.0
a(4) = 5.0
print*,'test'
!a_mx_p = mxCreateNumericMatrix(4, 1, 6, 0) ! 6 is ID for 'double'
!a_dx_p = mxGetData(a_mx_p)
!call mxDestroyArray(a_mx_p) ! bugged
call matlibTerminate()
end |
The commented stuff made the program crash, it compiled fine.
I can only call matlibInitialize and matlibTerminate without an error so far.
The code was compiled with
Code: | ftn95 test.f90 /import_lib matlib.dll
slink test.obj matlib.dll |
Will be doing further tests with more dll's later this day (for example libmx.dll, where all the mx-functions should residate, which made the program crash so far).
I will also try to get the functions from 'kernel32' to work, as you pointed out, where I could start with that.
Greetings,
Benjamin.
P.S. Excuse me for not cleaning the code completly of the unused funtcions and vars, I'm off to the dentist right now.
Update:
I get the C-functions from the libmx.dll to work now, thanks for the clue t work on both differentiated Paul (and those are STDCALL). Next I will try to mix the C_EXTERNAL and STDCALL together.
Main Problem is now 'mxCopyReal8ToPtr' as it is a fortran subroutine, which does not work with ftn95 yet.
Which kind of .lib-file would I use with ftn95? These are the alternatives:
borland, lcc, watcom and microsoft (which I use with DF).
I'll post the code later.
Greetings,
Benjamin. _________________ 42 |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7942 Location: Salford, UK
|
Posted: Wed Dec 20, 2006 8:57 am Post subject: |
|
|
Benjamin
My recommendation is still the same. Start with the information on MATLAB in the Knowledge base of this forum. This contains the work I did to get MATLAB working with FTN95. When you use this information you will probably not need a third party DLL.
Using MATLAB (post version 6.5) requires F_STDCALL when used with FTN95. |
|
Back to top |
|
|
Moredom
Joined: 12 Dec 2006 Posts: 5 Location: Germany, Harz-Mountains
|
Posted: Wed Dec 20, 2006 12:08 pm Post subject: |
|
|
Hi Paul!
I'm still searching the knowledge base, so far only information on calling Fortran from MatLab.
You understood me with the point that I have to call MatLab from Fortran and not the other way around?
The .m-file is closed source and not supposed to be seen by others.
Greetings,
Benjamin. _________________ 42 |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7942 Location: Salford, UK
|
Posted: Wed Dec 20, 2006 1:37 pm Post subject: |
|
|
Benjamin
Sorry I missed the point.
If you are sure about cdecl then you are right to use C_EXTERNAL but /IMPORT_LIB is for importing STDCALL Fortran routines. In this situation you do not need to refer to matlib.dll on the FTN95 command line. All the information the compiler needs is supplied via the C_EXTERNAL (or STDCALL) statements in the code. You will need to link (SLINK) with matlib.dll as you indicate.
Linking with third party DLLs is always going to be rather tricky. As a minimum the object code must follow the COFF standard. It might be a lot easier if you had access to the source code so that you could compile it using SCC (if indeed it is written in C/C++). |
|
Back to top |
|
|
Moredom
Joined: 12 Dec 2006 Posts: 5 Location: Germany, Harz-Mountains
|
Posted: Wed Dec 20, 2006 3:00 pm Post subject: |
|
|
Hi Paul!
I have the possibility to get access to the source and .h and .c files of the MatLab project.
The group of people who are going to get the finished .dll are the ones who should not have access to the source.
On the other hand, we don't have access to their fortran-source... (we know they are using the ftn95 compiler).
At this moment, I'm trying compile those sources. I have only VC 8 libraries and headers, and stumbling into a lot of error codes.
Do you have a pointer where I could take a look to get those MatLab generated files compiled with scc?
Furthermore on the idea before that one (trying with C_EXTERNAL):
I now get the mx-functions _or_ the initialization and termination to work with ftn95. As soon as I cleaned that code a little bit up, I will post it.
Greetings,
Benjamin _________________ 42 |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7942 Location: Salford, UK
|
Posted: Thu Dec 21, 2006 9:21 am Post subject: |
|
|
Benjamin
SCC is the C/C++ compiler that is shipped with FTN95. It is fully supported by Plato3 (and prossibly by the VS plug-in as well). |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|