求助fortran中编译matlab数学引擎
有没有具体的在fortran中编译matlab数学引擎的具体过程,我按刘志检的书做了,但是在dos环境下不能运行:libeng.def,libmex.def,libnix.def,libmat.def和Maflab.def这几个命令,生成连接库,所以想请教有没有具体的编译步骤,或是参考文献,非常希望大家帮助。回复:(soulzhao)求助fortran中编译matlab数学引擎
<P>你的意思是不是fortran调用matlab程序?下面的文章应该对你有帮助<BR><BR>如何由Fortran中呼叫MATLAB的M檔案 <BR>基本的作法是先將M檔案轉換為.dll檔 <BR>再由Fortran去呼叫之 <BR><BR>程式是使用 Matlab 6.5.1 <BR>Matlab compiler v3.0.1 <BR>Compaq Visual Fortran Pro v6.6.0 (CVF) (Compaq bought DEC and HP bought Compaq) <BR><BR>原始m檔案為 <BR><BR>function b= matlabinc(a) <BR>% Increment given argument a and return result b to caller, displaying both on screen as well <BR>disp(a) <BR>explore(a) <BR>b = a + 1; <BR>disp(b) <BR>explore(b) <BR><BR>使用以下的方式compile 為DLL <BR>eval(['mcc -t -L C -W lib:QuGeneLib -T link:lib -h ' progName '.m libmmfile.mlib']) <BR><BR>%如果m 檔案中有繪圖請使用以下方式 <BR>%eval(['mcc -B sgl -t -L C -W libhg:QuGeneLib -T link:lib -h ' progName '.m libmmfile.mlib']) <BR><BR>以下為原始檔與描述 <BR>This heavily commented Fortran program serves as a simple example on how a MATLAB .m file can be called from Fortran. Suitable if this is your first time trying this. <BR><BR>The basic mechanism is to pack the C-compiled .m into a .dll and link to it from Fortran. Argument and result xfer mechanism is explained so that program can be easily expanded. <BR><BR>程式開始 <BR>以下藍色部分為MATLAB中使用方式 <BR>藍色以下部分為Fortran中使用方式 <BR><BR>program test <BR><BR>!=============================================================================================================== <BR>! <BR>! This program serves as a simple example on how to interface a Fortran program to Matlab, <BR>! not the other way round which is well documented elsewhere. <BR>! <BR>! <BR>! ENVIRONMENT <BR>! This will work using the following environment on a Windows XPpro PC, other environments have not been tested <BR>! but may work as well. <BR>! <BR>! * Matlab v6.5.1 R13 SP1 <BR>! * Matlab compiler v3.0.1 <BR>! * Compaq Visual Fortran Pro v6.6.0 (CVF) (Compaq bought DEC and HP bought Compaq) <BR>! <BR>! <BR>! OVERVIEW <BR>! We start with a simple .m script and create C-code from it, which is then compiled and placed into a .dll. <BR>! This process is performed fairly automatic in the Matlab environment. <BR>! <BR>! Now we write a Fortran program that calls this Matlab routine. For this to work properly we have to setup <BR>! Matlab structures containing the data values (the mx array and pointers to it), take care of the underscores <BR>! added to routine names in dll's, the way the arguments are referenced because the routine was generated <BR>! from C-code and the fact that the routine resides in a dll. All this need only be done for the Matlab script <BR>! we create, we may call any mx* routines in a normal Fortran fashion. All this is described in detail now. <BR>! <BR>! <BR>! DETAIL <BR>! Our task is to call the following Matlab script from a Fortran program. <BR>! <BR>! function b = matlabinc(a) <BR>! % Increment given argument a and return result b to caller, displaying both on screen as well <BR>! disp(a) <BR>! explore(a) <BR>! b = a + 1; <BR>! disp(b) <BR>! explore(b) <BR>! <BR>! We compile our Matlab script using a function like this <BR>! <BR>! function compileDLL(progName) <BR>! % Compile the .m file given and place result into a dll <BR>! eval(['mcc -t -L C -W lib:QuGeneLib -T link:lib -h ' progName '.m libmmfile.mlib']) <BR>! % Use this line instead if you call graphics routines in your .m file <BR>! %eval(['mcc -B sgl -t -L C -W libhg:QuGeneLib -T link:lib -h ' progName '.m libmmfile.mlib']) <BR>! <BR>! This will create two files, QuGeneLib.lib and QuGeneLib.dll. The.lib file contains information for the Fortran <BR>! compiler on what is in the .dll file. The .dll is the dynamic link library that contains our compiled Matlab <BR>! routine. Copy both to the Fortran development directory were the .f90 files live. Also copy all Matlab .dll's <BR>! you are using to the same location, libmx.dll is one you will definitely need. If you call graphics routines <BR>! you will also need sgl.dll and you have to place FigureMenuBar.fig and FigureToolBar.fig into the path of <BR>! the executing Fortran program as well. <BR>! <BR>! In CVF use "project->add to project->files" and pick the QuGeneLib.lib file. Read through the comments in this <BR>! Fortran program to understand how everything works. You can use the DOS command <BR>! <BR>! dumpbin/exports libmx.lib <BR>! <BR>! or the Windows Dependency Walker <BR>!!http://www.dependencywalker.com/ <BR>! <BR>! to see the names of the routines included in the corresponding .dll, this is what has to go into the <BR>! ALIAS directive when defining the interface for the C routine in the dll with the !DEC$ compiler statement. <BR>! You will note an added underscore and sometimes also a @number after the name. The number indicates the number <BR>! of bytes used for arguments. Also, C is case sensitive so cases in routine names must match. <BR>! <BR>! Note: You do not need to do this for any mx* routines, Matlab has defined an API for all of these. Although you will <BR>! encounter a name such as MXCOPYPTRTOREAL8@12 in libmx.lib, you have to call mxCopyPtrToReal8 instead. <BR>! <BR>! The main way of achieving data transfer between Fortran and the Matlab C program created from our .m file script <BR>! is via the mx routines supplied by Matlab in the libmx.dll. Read through Matlab HELP titled <BR>! "External Interfaces/API Reference: Fortran MX-Functions" before expanding this example. <BR>! <BR>! Note: You do not need to define any interfaces, pointers etc for the mx* routines. You do also not need <BR>! to call loadlibrary or getprocaddress for the mx* routines. It will not work if you do any of this. <BR>! <BR>! <BR>! Alex Pudmenzky, 24 September 2003, The University of Queensland, Brisbane, Australia (http://alex.pudmenzky.com).! <BR>!=============================================================================================================== <BR>! Declaration section <BR><BR>! Definitions for the "loadlibrary", "freelibrary" and "getprocaddress" routines are included in the following files <BR>!use dfwin ! More stuff than is in kernel32 <BR>use kernel32 ! Use this to safe compilation time if other stuff is not needed <BR><BR>IMPLICIT NONE ! Produce error during compilation if variables aren't declared <BR><BR>!--------------------------------------------------------------------------------------------------------------- <BR>INTERFACE <BR><BR>! Define the interfaces to our own Matlab scripts <BR>! The LibInitialize() and LibTerminate() routines are automatically added by the compilation <BR>! and dll creation progress in Matlab. <BR>SUBROUTINE matlabinc(nlhs,plhs, nrhs,prhs) <BR>integer*4 :: nlhs,nrhs <BR>integer*4 :: plhs(*),prhs(*) <BR>!DEC$ ATTRIBUTES C, DLLIMPORT, ALIAS:"_mlxMatlabinc" :: matlabinc <BR>!DEC$ ATTRIBUTES VALUE :: nlhs,nrhs <BR>!DEC$ ATTRIBUTES REFERENCE :: plhs,prhs <BR>END SUBROUTINE <BR><BR>SUBROUTINE QuGeneLibInitialize() <BR>!DEC$ ATTRIBUTES C, DLLIMPORT, ALIAS:"_QuGeneLibInitialize" :: QuGeneLibInitialize <BR>END SUBROUTINE <BR><BR>SUBROUTINE QuGeneLibTerminate() <BR>!DEC$ ATTRIBUTES C, DLLIMPORT, ALIAS:"_QuGeneLibTerminate" :: QuGeneLibTerminate <BR>END SUBROUTINE <BR><BR>END INTERFACE <BR><BR>!--------------------------------------------------------------------------------------------------------------- <BR>! This part only required for our own Matlab routine, not the mx* routines <BR>integer :: p_QuGeneLib_dummy, p_libmx_dummy <BR>logical :: status <BR><BR>! QuGeneLib.dll <BR>pointer (p_QuGeneLib,p_QuGeneLib_dummy) <BR>pointer (pr1_QuGeneLib,QuGeneLibInitialize) <BR>pointer (pr2_QuGeneLib,matlabinc) <BR>pointer (pr3_QuGeneLib,QuGeneLibTerminate) <BR><BR>!--------------------------------------------------------------------------------------------------------------- <BR>! Declare all mx* routines we call <BR>INTEGER*4 :: mxGetData ! <BR>INTEGER*4 :: mxGetNumberOfElements ! <BR>INTEGER*4 :: mxCreateScalarDouble ! <BR>INTEGER*4 :: mxCreateNumericMatrix ! <BR>INTEGER*4 :: mxClassIDFromClassName ! <BR><BR>!--------------------------------------------------------------------------------------------------------------- <BR>real*8 :: a(3) ! What I store in Matlab mx array <BR>real*8 :: b(3) ! What I read out of Matlab mx array <BR>integer*4 :: a_mx_p ! Pointer to mx array for a <BR>integer*4 :: a_dx_p ! Pointer to data in mx array for a <BR>integer*4 :: b_mx_p ! Pointer to mx array for b <BR>integer*4 :: b_dx_p ! Pointer to data in mx array for b <BR>integer*4 :: na ! Number of entries in a <BR>integer*4 :: nb ! Number of entries in b <BR><BR>!=============================================================================================================== <BR>! Executable section <BR><BR>! Locate the QuGeneLib.dll and load it into memory <BR>! This library contains all of our own Matlab functions <BR>p_QuGeneLib = loadlibrary("QuGeneLib.dll"C) <BR>if (p_QuGeneLib == 0) then <BR>type *, "Error occurred opening QuGeneLib.dll" <BR>type *, "Program aborting" <BR>goto 1000 <BR>endif <BR><BR>! Set up a pointers to the routines of interest <BR>pr1_QuGeneLib = getprocaddress(p_QuGeneLib, "_QuGeneLibInitialize"C) <BR>if (pr1_QuGeneLib == 0) then <BR>type *, "Error occurred finding _QuGeneLibInitialize in QuGeneLib.dll" <BR>type *, "Program aborting" <BR>goto 1000 <BR>endif <BR><BR>pr2_QuGeneLib = getprocaddress(p_QuGeneLib, "_mlxMatlabinc"C) <BR>if (pr2_QuGeneLib == 0) then <BR>type *, "Error occurred finding _mlxMatlabinc in QuGeneLib.dll" <BR>type *, "Program aborting" <BR>goto 1000 <BR>endif <BR><BR>pr3_QuGeneLib = getprocaddress(p_QuGeneLib, "_QuGeneLibTerminate"C) <BR>if (pr3_QuGeneLib == 0) then <BR>type *, "Error occurred finding _QuGeneLibTerminate in QuGeneLib.dll" <BR>type *, "Program aborting" <BR>goto 1000 <BR>endif <BR><BR>!=============================================================================================================== <BR>! Initialise interface to our Matlab routine <BR>! (this initialisation routine is automatically created by Matlab during compilation) <BR>call QuGeneLibInitialize() <BR><BR>! The real*4 value we want to pass from this Fortran code to our Matlab routine <BR>a(1) = 1.0 <BR>a(2) = 2.0 <BR>a(3) = 3.0 <BR><BR>! Create mx array for this value and remember pointer to that mx array (not the value!) <BR>! The mx Array is a special structure that can contain any Matlab datatype <BR>! We omit checking pointers from here on to preserve simplicity, if they are returned zero the operation failed <BR>!a_mx_p = mxCreateScalarDouble(a) <BR>a_mx_p = mxCreateNumericMatrix(3, 1, mxClassIDFromClassName('double'), 0) <BR><BR>! Remember pointer to the data in the mx array, given the pointer to the mx array itself <BR>a_dx_p = mxGetData(a_mx_p) <BR><BR>type *, a <BR>! Store data in Matlab mx array <BR>call mxCopyReal8ToPtr(a, a_dx_p, 3) <BR><BR>! Now we want to prove the data above has been stored by retrieving it again <BR><BR>! Retrieve the number of values (elements) in the mx array, given the pointer to the mx array (not the value!) <BR>na = mxGetNumberOfElements(a_mx_p) <BR><BR>! Check <BR>type *, na <BR><BR>! Now call our Matlab routine which returns b given the argument a (actually pointers to a & b) <BR>call matlabinc(1,b_mx_p, 1,a_mx_p) <BR><BR>! Retrieve data pointer given the mx array pointer <BR>b_dx_p = mxGetData(b_mx_p) <BR><BR>! Convert the value(s) stored in the mx array to Fortran representation, given the pointer to the data in the mx array <BR>call mxCopyPtrToReal8(b_dx_p, b, 3) <BR><BR>! Just to see if it worked <BR>type *, b <BR><BR>! Release memory <BR>call mxDestroyArray(a_mx_p) <BR>call mxDestroyArray(b_mx_p) <BR><BR>! Terminate interface to our Matlab routine <BR>! (this termination routine is automatically created by Matlab during compilation) <BR>call QuGeneLibTerminate() <BR><BR>1000 continue <BR><BR>! Release library <BR>status = freelibrary(p_QuGeneLib) <BR><BR>end <BR></P>
页:
[1]