How to call MATLAB M archives by Fortran

zhaozj2021-02-16  103

How to call MATLAB MATLAB in Fortran is to convert M file to .dll files and then call up by Fortran to call the Co-calls to use Matlab 6.5.1 Matlab Compiler V3.0.1 Compaq Visual Fortran Pro v6.6.0 (CVF) (Compaq Bought Dec And HP Bought Compaq) Original M File for Function B = Matlabinc (A)% Increment Given Argument A and Return Result B TO Caller, Displaying Both On Screen As Well Disp (a) Explore (a) B = A 1; DISP (b) Explore (b) use the following way compile for DLL EVAL (['mcc -t -lc -wlc -wlib: queenelib -t link: lib -h' progname '.m libmmfile.mlib'])% If you have a drawing in the m file, use the following manual EVAL (['mcc -b sgl -t -lc -wlc: queGenelib -t link: lib -h' progName '.m libmmfile.mlib']) or below and description 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. 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. The following blue section is used for use in MATLAB. The following sections are used in Fortran. Program Test! ==== =========== ============================================================================================================================================================================================================= ==============================================

!! This program serves as a simple example on how to interface a Fortran program to Matlab,! Not the other way round which is well documented elsewhere.!!! ENVIRONMENT! This will work using the following environment on a Windows XPpro PC, other Environments Have Not Been Tested! Butray Work As Well.!! * Matlab V6.5.1 R13 SP1! * Matlab Compiler V3.0.1! * Compaq Visual Fortran Pro v6.6.0 (CVF) (Compaq Bought Dec And HP Bought Compaq)! !! OVERVIEW! We start with a simple .m script and create C-code from it, which is then compiled and placed into a .dll.! This process is performed fairly automatic in the Matlab environment.!! Now we write a Fortran program that calls this Matlab routine. For this to work properly we have to setup! Matlab structures containing the data values ​​(the mx array and pointers to it), take care of the underscores! added to routine names in dll's, the way the arguments Are Reference Because The Routine Was generated! from c-code and the fact th At The Routine Resides in A DLL. All this next.com! We create, We May Call Any Mx * Routines in a Normal fortran fashion. All this is described in detail now.!!! Detail! o o is to call the following Matlab script from a Fortran program.!! function b = matlabinc (a)!% Increment given argument a and return result b to caller, displaying both on screen as well! disp (a)! explore (a) ! b = a 1;! DISP (b)! Explore (b)!! We Compile Our Matlab Script Using A Function Like this !! Function Compiledll (ProgName)!% Compile The .m File Given and Place Result Into A DLL ! Eval (['mcc -t -lc -w lib: quenerib -t link: lib -h' progName '.m libmmfile.mlib'

])!% Use this line instead if you call graphics routines in your .m file!% EVAL (['mcc -b sgl -t -lc -wlibhg: queenelib -t link: lib -h' progname '.m libmmfile .mlib ']) !! This Will Create Two files, queenelib.lib and quimenerib.dll. The.lib file contacts information for the fortran! compiler on what is in .dll file. The .dll is the Dynamic Link Library That contains our compiled Matlab! routine. Copy both to the Fortran development directory were the .f90 files live. Also copy all Matlab .dll's! you are using to the same location, libmx.dll is one you will definitely need. If you call graphics routines! you will also need sgl.dll and you have to place FigureMenuBar.fig and FigureToolBar.fig into the path of! the executing Fortran program as well.!! In CVF use "project-> add to project-> files" and Pick the qgenelib.lib file. Read through The Comments in this! Fortran Program To understand how everything works. You can use the dos command!! Dumpbin / exports libmx.lib!! or the Windows Dependency Walker !! http://www.dependencywalker.com/!! to see the names of the routines included in the corresponding .dll, this is what has to go into the! ALIAS directive when defining the interface for the C routine in the dll with the! DEC $ compiler statement.! You will note an added underscore and sometimes also a @number after the name. The number indicates the number! of bytes used for arguments. Also, C is case sensitive so cases In Routine Names Must Match.!! NOTE: You Do Not Need to do this for any mx * routines, matlab HAS Defined An Api for all of these. Alth You Will! Encounter a name such as mxcopyptrtoreAl8 @

12 in libmx.lib, you have to call mxCopyPtrToReal8 instead.!! The main way of achieving data transfer between Fortran and the Matlab C program created from our .m file script! Is via the mx routines supplied by Matlab in the libmx.dll . Read through Matlab HELP titled "External Interfaces / API Reference: Fortran MX-Functions"!.!! before expanding this example Note: You do not need to define any interfaces, pointers etc for the mx * routines You do also not need. !. to call loadlibrary or getprocaddress for the mx * routines It will not work if you do any of this Alex Pudmenzky, 24 September 2003, The University of Queensland, Brisbane, Australia (http:.!!! //alex.pudmenzky. COM).!! =============================================== ============================================================================================================================================================================================================= =================================1 "LoadLibrary", "FreeElibrary" and "getProcaddress" Routines Are INCLUDED IN The FOLLOWING FILES! USE DFWIN! More Stuff Than Is in Kernel32 USE KERNEL3 2! Use this to save compilation time if other stuff is not needed Implicit None! Produce Error During Compilation IF VARIABLES AREN '

T Declared! ----------------------------------------------- -------------------------------------------------- -------------- INTERFACE! Define the interfaces to our own Matlab scripts! The LibInitialize () and LibTerminate () routines are automatically added by the compilation! and dll creation PROGRESS IN MATLAB. Subroutine Matlabinc (NLHS, PLHS, NRHS, PRHS) INTEGER * 4 :: NLHS, NRHS Integer * 4 :: PLHS (*), PRHS (*)! DEC $ Attributes C, Dllimport, Alias: "_ mlxmatlabinc" !! :: matlabinc DEC $ ATTRIBUTES VALUE :: nlhs, nrhs DEC $ ATTRIBUTES REFERENCE :: plhs, prhs END SUBROUTINE SUBROUTINE QuGeneLibInitialize () DEC $ ATTRIBUTES C, DLLIMPORT, ALIAS:! "_ QuGeneLibInitialize" :: QuGeneLibInitialize END SUBROUTINE SUBROUTINE QuGeneLibTerminate ( )! DEC $ Attributes C, Dllimport, Alias: "_ QuGenelIbterminate"

:: QuGenelIbterminate End Subroutine End Interface! ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- -------------------! This part only remove for ot ownel qg in in::, l l, l,,,,,,,,,,,,,,,,,,,, 特 特 特 特 特 特 特 特 特 特 特 特 特 特, (p_quGenelib, p_qugenely) Pointer (Pr1_QUGENELIB, QUGENELIBIENELIBINITIAALIZE) POINTER (Pr2_QUGENEANELIB, MATLABINC) Pointer (Pr3_Qugenelib, QuGenelibterminate)! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -------------------------------------------------- -----------------------------------! Declare all mx * routines we call integer * 4 :: mxgetdata! Integer * 4 :: MxGetNumberofelements! Integer * 4 :: MXCREATESCALARDOUBLE! INTEGER * 4 :: MXCREATENUMERICIMATRIX! Integer * 4 :: mxclassidfromclassname!! --------------------- -------------------------------------------------- ---------------------------------------- REAL * 8 :: A (3)! What i store in matlab mx array real * 8 :: b (3)! What i read out of mat Lab 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! ================ ============================================================================================================================================================================================================= =====================================================================================================================================================

======================================================================================================================================================================================================================================================================================★ "QuGeneLib.dll" C) if (p_QuGeneLib == 0) then type *, "Error occurred opening QuGeneLib.dll" type *, "Program aborting" goto 1000 endif! Set up a pointers to the routines of interest pr1_QuGeneLib = getprocaddress ( p_QuGeneLib, "_QuGeneLibInitialize" C) if (pr1_QuGeneLib == 0) then type *, "Error occurred finding _QuGeneLibInitialize in QuGeneLib.dll" type *, "Program aborting" goto 1000 endif pr2_QuGeneLib = getprocaddress (p_QuGeneLib, "_mlxMatlabinc" C) if (pr2_QuGeneLib == 0) then type *, "Error occurred finding _mlxMatlabinc in QuGeneLib.dll" type *, "Program aborting" goto 1000 endif pr3_QuGeneLib = getprocaddress (p_QuGeneLib, "_QuGeneLibTerminate" C) if (pr3_QuGeneLib == 0) then type *, "Error Occurred Finding _QuGenelibterminate In QuGenelib.dll" Type *, "Program Aborting" goto 1000 EN DIF! ============================================================================================================================================================================= ============================================================================================================================================================================================================= ====

=========! Initialise interface to our Matlab routine! (This initialisation routine is automatically created by Matlab during compilation) call QuGeneLibInitialize ()! The real * 4 value we want to pass from this Fortran code to our Matlab Routine A (1) = 1.0 a (2) = 2.0 a (3) = 3.0! Create MX Array for this value and repeem Pointer To That MX Array !! The MX Array Is A Special Structure That Can Contain any Matlab datatype! We omit checking pointers from here on to preserve simplicity, if they are returned zero the operation failed! a_mx_p = mxCreateScalarDouble (a) a_mx_p = mxCreateNumericMatrix (3, 1, mxClassIDFromClassName ( 'double'), 0)! Remember pointer to the data in the mx array, given the pointer to the mx array itself a_dx_p = mxGetData (a_mx_p) type *, a! Store data in Matlab mx array call mxCopyReal8ToPtr (a, a_dx_p, 3)! Now we want to prove the data Above Has Been Stored by Retrieving It Again! Retrieve The Number of Values ​​(Elements) in The MX Array, Given the pointer to the mx array (not the value!) na = mxGetNumberOfElements (a_mx_p)! Check type *, na! Now call our Matlab routine which returns b given the argument a (actually pointers to a & b) call matlabinc (1, B_mx_p, 1, a_mx_p)! Retrieve Data Pointer Given The MX Array Pointer B_DX_P =

转载请注明原文地址:https://www.9cbs.com/read-10882.html

New Post(0)