lyyzby 发表于 2008-3-12 15:46:49

[请教]Fortran程序里调用matlab函数

有没有人有Fortran程序里调用matlab函数的例子,具体怎么操作啊,看一些相关的都看不明白

chyg31 发表于 2008-3-20 11:21:36

很感兴趣,以前在做,现在没有时间,唉
MatlabX库包括数学运算、功能强大线性代数、
图形处理等功能和部分神经网络,用于扩展 MATLAB 的功能和运行速度,可以作为独立的工具使用,支持生成自己的独立运行程序,不要求客户电脑装有matlab。

在VB,VC,Dephi中使用该数学工具包可避免重复性劳动,从而减少开发人员实现算法和界面设计的困难,可大大提高开发效率,
http://matlabvbvc.blog.163.com/

taohe 发表于 2008-3-21 21:35:43

不知道楼主还在关注这贴,下面给出一个在fortran中调用matlab编译生成的DLL的例子。

【试验环境】Windows 2003 server std,matlab r2007b,MinGW gcc 4.2 (sjlj)。Visual Studio 2005
【试验任务】实现在fortran程序中调用matlab编译生成的DLL。
【试验步骤】首先,创建一个简单的m代码,这里用拙作《深入浅出matlab7.x混合编程》中用到的mcctest01.m作为例子,它是一个很简单的m方程,程序代码如下:function mcctest01
% MCCTEST01 Create some data and draw a 2D x-y plot
%   mcctest01 is used to demonstrates how to convert M-functions into   
%   library files and how to use created library files with MFC
%   applications.
%
%   Inputs:
%       None
%   
%   Output:
%       None

%
%   Copyright (c) 2005 Dong Weiguo

% create data
x = 0:.01:20;
y = x.*sin(x);

% draw a plot
plot(x,y);
xlabel('x');
ylabel('y');然后在matlab中编译mcctest01,生成libmcctest01.dll。注意,如果这是你第一次在matlab中使用mcc命令,你需要先运行mbuild -setup来配置。我使用Visual Studio 2005编译器。在matlab中执行如下命令:mcc -W cpplib:libmcctest01 -T link:lib mcctest01.m这里假设matlab中的当前工作环境是$MATLAB\work。结果将会产生若干文件,我们需要拷贝如下四个文件到我们的Fortran源程序目录:libmcctest01.h
libmcctest01.lib
libmcctest01.dll
libmcctest01.ctf接下来的任务就是如何在fortran程序中调用libmcctest01.dll。暂告一段落,在下面帖子中介绍。

taohe 发表于 2008-3-21 21:52:56

Fortran无法直接使用动态链接库(或者有些版本的fortran编译器,比如PGI,或Visual Fortran等有相关的扩展,不过我不了解)。长话短说,在fortran程序中,我们可以通过调用c语言的方式间接调用dll,具体的做法是我们为调用dll中的函数,另外在写一个和fortran兼容的c或c++语言的wrapper函数。这里牵涉到fortran和c/c++的混合编程,主要有两点需要注意的:1. Fortran程序中函数的参数是以地址的方式传递的。也就是说类似于
subroutine foo(x, y, z)
real x, y, z

其等效的c语言函数声明则类似
void foo( float* x, float* y, float* z);

2. 有些fortran编译器比如g77,在编译函数后会在函数名的后面在多加一个下划线“_",也就是上面的subroutine foo编译后,函数名就变成了foo_。换句话说,如果在fortran中用
call foo(...)
调用foo子函数,其实是找foo_。说起来好像挺烦的,不过做几次练习以后就熟悉了。

下面给出针对于我们的例子,也就是libmcctest01.dll中mcctest01函数的调用,一个可行的C++语言的wrapper函数:// File: mcctest01wrap.cpp
// Description: A simple testing c++ souce file. Two functions
// are defined, which will be called in a FORTRAN 77 code.
//
// History: Created on 16 January, 2006
// Created by: Dong Weiguo
//////////////////////////////////////////////////////////////

#include "libmcctest01.h"

// By default, most of fortran compilers would add an
// undrescore at the end of function name
// So let's emulate this bahavior
extern "C" void mymccfunc_()
{
   libmcctest01Initialize();
         mlxMcctest01(0, NULL, 0, NULL);
         std::cout << "Press any key to quit!" << std::endl;
         getchar();
   libmcctest01Terminate();
}


// Another way to deal with this underscore thing is to
// use some compiler flag to disable it. For example, we
// can use "-fno-underscoring -fno-second-underscore" for
// g77.
extern "C" void mymccfunc()
{
   libmcctest01Initialize();
   mlxMcctest01(0, NULL, 0, NULL);
   libmcctest01Terminate();
}这样,我们只要在fortran程序中调用某个wrapper函数,比如mymccfunc_就可以了。下面是这个例子的fortran主程序:C      A test program to demonstrate how to call c++
C      functions from a Fortran program.
C      Synopsis: f77cpptst
C      History: 16 January, 2006
C      Created by: Dong Weiguo

       program f77cpptst
      
       call mymccfunc()

       stop
       end可以看出,程序非常简单,就是调用wrapper函数。接下来就开始介绍如何编译我们的例子。

[ 本帖最后由 taohe 于 2008-3-21 22:14 编辑 ]

taohe 发表于 2008-3-21 22:04:28

在这个例子中我用一个Makefile,通过调用gnu-make来实现例子程序的编译。这样作的好处是可方便的移植到其他平台,比如Linux(如果有时间,我再介绍一下在Linux上完成这个例子)。# makefile for f77mcctst on Windows by using MinGW

CC =
G77 = i:\mingw\bin\gfortran-sjlj.exe
CFLAGS = -Wall -g -Ih:\MATLABr2007b\extern\include
FFLAGS = #-fno-underscoring -fno-second-underscore
LDFLAGS = -LH:\MATLABr2007b\extern\lib\win32\microsoft

MYEXE = f77mcctst.exe
MYOBJS = f77mcctst.o mcctest01wrap.o

#default target = all
all :$(MYEXE)

$(MYEXE) : $(MYOBJS)
      $(G77) -o $(MYEXE) $(MYOBJS) libmcctest01.lib mclmcrrt.lib$(LDFLAGS) -lm -lstdc++
      
mcctest01wrap.o : mcctest01wrap.cpp
      g++-sjlj -c $(CFLAGS) mcctest01wrap.cpp

f77mcctst.o : f77mcctst.for
      $(G77) -c $(FFLAGS) f77mcctst.for


clean:
      del *.o
      del $(MYEXE)然后在DOS命令行运行如下命令进行编译:I:\dwg\fortran\f77mcc_r2007b>mingw32-make其中mingw32-make是我用的MinGW中的make命令。

附件是这个例子所有文件的打包。

【注意事项】
1. 如果用MinGW 的gcc/g77的话,我们需要修改matlab r2007b中给出的mclmcr.h,打包文件中有我改过的mclmcr.h,你们可以把系统自带的做一个拷贝,然后把附件中的mclmcr.h_updated拷贝成mclmcr.h。
2. 使用MinGW的主要原因是它可以免费获得。如果你用不同版本的编译器,或者matlab,请根据自己的情况作相应的修改。

[ 本帖最后由 taohe 于 2008-3-21 22:10 编辑 ]

taohe 发表于 2008-3-21 22:14:45

在这个例子中我用一个Makefile,通过调用gnu-make来实现例子程序的编译。这样作的好处是可方便的移植到其他平台,比如Linux(如果有时间,我再介绍一下在Linux上完成这个例子)。# makefile for f77mcctst on Windows by using MinGW

CC =
G77 = i:\mingw\bin\gfortran-sjlj.exe
CFLAGS = -Wall -g -Ih:\MATLABr2007b\extern\include
FFLAGS = #-fno-underscoring -fno-second-underscore
LDFLAGS = -LH:\MATLABr2007b\extern\lib\win32\microsoft

MYEXE = f77mcctst.exe
MYOBJS = f77mcctst.o mcctest01wrap.o

#default target = all
all :$(MYEXE)

$(MYEXE) : $(MYOBJS)
        $(G77) -o $(MYEXE) $(MYOBJS) libmcctest01.lib mclmcrrt.lib$(LDFLAGS) -lm -lstdc++
       
mcctest01wrap.o : mcctest01wrap.cpp
        g++-sjlj -c $(CFLAGS) mcctest01wrap.cpp

f77mcctst.o : f77mcctst.for
        $(G77) -c $(FFLAGS) f77mcctst.for


clean:
        del *.o
        del $(MYEXE)然后在DOS命令行运行如下命令进行编译:I:\dwg\fortran\f77mcc_r2007b>mingw32-make其中mingw32-make是我用的MinGW中的make命令。

lyyzby 发表于 2008-3-24 18:17:39

回复 6# 的帖子

非常感谢,我去试试

taohe 发表于 2008-3-24 20:35:53

原帖由 lyyzby 于 2008-3-24 18:17 发表 http://www.simwe.com/forum/images/common/back.gif
非常感谢,我去试试

后来我想起来,我以前贴过一个帖子,介绍如何在Fortran中调用matlab编译的库函数。下面是连接:
http://www.simwe.com/forum/viewthread.php?tid=740677&highlight=

不过那贴是以matlab6.5.1作为例子的,可以和这次的结合起来看。

huiwei 发表于 2008-3-25 14:39:50

我想用matlab拟合曲线,以前没用过matlab,不知道是不是很难

taohe 发表于 2008-3-25 21:45:43

原帖由 huiwei 于 2008-3-25 14:39 发表 http://www.simwe.com/forum/images/common/back.gif
我想用matlab拟合曲线,以前没用过matlab,不知道是不是很难

应该不是很难,它毕竟只是一个工具软件,而且又有大量的参考资料。不过也要注意到,它是个复杂的工具软件,所以在刚开始的时候,要花点功夫。

geni 发表于 2009-1-2 22:53:09

原帖由 taohe 于 2008-3-25 21:45 发表 http://forum.simwe.com/images/common/back.gif


应该不是很难,它毕竟只是一个工具软件,而且又有大量的参考资料。不过也要注意到,它是个复杂的工具软件,所以在刚开始的时候,要花点功夫。

不知taohe兄有否试过用1stopt来调用matlab生成的dll? 还有matlab生成的mat文件(NN网络)可否也能生成dll?
以前没有用过混合编程,现在想用1stopt优化matlab生成的dll,   问题可能比较幼稚。

[ 本帖最后由 geni 于 2009-1-2 23:31 编辑 ]

taohe 发表于 2009-1-3 10:46:11

原帖由 geni 于 2009-1-2 22:53 发表 http://forum.simwe.com/images/common/back.gif


不知taohe兄有否试过用1stopt来调用matlab生成的dll? 还有matlab生成的mat文件(NN网络)可否也能生成dll?
以前没有用过混合编程,现在想用1stopt优化matlab生成的dll,   问题可能比较幼稚。


matlab产生的DLL就是一般的Win32 DLL文件,所以只要1stopt支持调用DLL文件,那么就是可行的。不过要注意matlab7.x编译的DLL文件在运行的目标电脑上需要MCR环境。

NN网络的训练有关的函数可能无法通过一般的编译技术编译成DLL文件,但是其他的,比如使用NN网络做预测都函数都是可以编译成DLL在其他程序中使用的。

smilemoon2009 发表于 2009-2-25 10:20:01

本帖最后由 kokyo52 于 2009-2-25 10:54 编辑

我写了一点关于Matlab混合编程的东西,大家可以参考一下
http://forum.simwe.com/thread-865964-1-1.html

yldpj 发表于 2010-1-6 23:05:05

各位高手,我在调用MATLAB,如下运行:
>> mex-setup

Select a compiler:
Lcc C version 2.4 in D:\MATLAB\sys\lcc
Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio

None

Compiler:
我安装的是cvf6.6,请问为什么MATLAB不识别,记得安装cvf6.6的时候环境变量好像有问题,难道真是环境变量的问题吗,还请taohe给以解答,非常感谢!

messenger 发表于 2010-1-7 14:54:19

Matlab版本号是多少?

各位高手,我在调用MATLAB,如下运行:
>> mex-setup

Select a compiler:
Lcc C version 2.4 in D:\MATLAB\sys\lcc
Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Stu ...
yldpj 发表于 2010-1-6 23:05 http://forum.simwe.com/images/common/back.gif

yldpj 发表于 2010-1-8 16:08:31

15# messenger

MATLAB版本是7.0,但是只有0.99G,不知道是不是文件不全的原因还是啥的?

cuitaihe 发表于 2011-6-13 15:21:19

不知道楼主还在关注这贴,下面给出一个在fortran中调用matlab编译生成的DLL的例子。

【试验环境】Windows 2003 server std,matlab r2007b,MinGW gcc 4.2 (sjlj)。Visual Studio 2005
【试验任务】实现在fortra ...
taohe 发表于 2008-3-21 21:35 http://forum.simwe.com/images/common/back.giftaohe,还在吗?为什么我运行这段代码的时候会出错呢?

cuitaihe 发表于 2011-6-13 15:24:50

1093428071Fortran无法直接使用动态链接库(或者有些版本的fortran编译器,比如PGI,或Visual Fortran等有相关的扩展,不过我不了解)。长话短说,在fortran程序中,我们可以通过调用c语言的方式间接调用dll,具体的做法是我们 ...
taohe 发表于 2008-3-21 21:52 http://forum.simwe.com/images/common/back.gif
页: [1]
查看完整版本: [请教]Fortran程序里调用matlab函数