forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Access to MatLab generated .dll using Fortran (ftn95)

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General
View previous topic :: View next topic  
Author Message
Moredom



Joined: 12 Dec 2006
Posts: 5
Location: Germany, Harz-Mountains

PostPosted: Sat Dec 16, 2006 4:33 pm    Post subject: Access to MatLab generated .dll using Fortran (ftn95) Reply with quote

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
View user's profile Send private message
DrTip



Joined: 01 Aug 2006
Posts: 74
Location: Manchester

PostPosted: Sat Dec 16, 2006 9:38 pm    Post subject: Reply with quote

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
View user's profile Send private message
Moredom



Joined: 12 Dec 2006
Posts: 5
Location: Germany, Harz-Mountains

PostPosted: Mon Dec 18, 2006 4:19 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Dec 19, 2006 9:36 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Moredom



Joined: 12 Dec 2006
Posts: 5
Location: Germany, Harz-Mountains

PostPosted: Tue Dec 19, 2006 10:24 am    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Wed Dec 20, 2006 8:57 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Moredom



Joined: 12 Dec 2006
Posts: 5
Location: Germany, Harz-Mountains

PostPosted: Wed Dec 20, 2006 12:08 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Wed Dec 20, 2006 1:37 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Moredom



Joined: 12 Dec 2006
Posts: 5
Location: Germany, Harz-Mountains

PostPosted: Wed Dec 20, 2006 3:00 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Thu Dec 21, 2006 9:21 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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