产生的DLL (VS2005, MATLAB7.5, mwArray)

简介:

程序中使用MATLAB编译产生的DLL (VS2005, MATLAB7.5, mwArray)

最近有几个帖子都在讨论有关在C++程序中使用MATLAB编译产生的动态链接库DLL。本 来想用原来帖子中给出的m代码作为例子,无奈那段代码其实无法执行。为了避免分散注意力,也为了更好地讨论问题,于是决定还是另外新开一个主题,以简单的 例子,和大家一起讨论如何在C++程序中使用matlab编译产生的DLL。

同时MATLAB最新版本R2007b刚刚发布不久,其中包含编译器4.7版,有了一些新的特性,于是也借这个例子来验证一下相关的技术有没有发生大的变化。

最近讨论的问题是关于在C++程序中调用MATLAB编译产生的动态链接库。具体的问题是在 调用DLL中函数时传递参数。我们知道,MATLAB可以把m代码编译成两种DLL,分别是C语言接口和C++语言接口的DLL。论坛上的问题是关于调用 C++接口的DLL中的函数,所以这里我们就以这种DLL为例来介绍。在C++接口的DLL中,函数的输入、输出参数都是mwArray对象。所以问题归 结为如何在C++程序中使用mwArray。

这个问题本来可以只用一个简单的C++程序来练习,而不需要MATLAB编译的DLL。不过为了模拟实际情况,选择以一个更为接近实际的m代码作为例子。在这个例子中,输入输出都是矩阵,至于标量,它也是一个一行、一列的矩阵。

实验环境:Windows 2003 Std Server with SP2 (En),MATLAB R2007b,Visual Studio 2005。MATLAB安装路径:h:MATLABR2007b。

实验内容:把一个简单的m代码编译成C++接口的DLL,然后在C++程序中调用。为了简单起见,这里的C++程序是一个Win32 Console程序,而不是Windows图形界面的程序,不过不妨碍我们的讨论。

下面是这个例子用到的m代码。它定义了一个名为myadd2的函数:

[Copy to clipboard] [ - ]

CODE:

function [y,z] = myadd2(a, b)

% dummy function, just to demonstrate the idea

y = a+b;

z = a+2*b;

end

首先把这个函数编译成C++接口的DLL。为此,我们需要先设置MATLAB编译器。具体做法是在MATLAB命令行执行“mbuild -setup”。然后用下面这行命令把myadd2函数编译成一个C++接口的DLL:

[Copy to clipboard] [ - ]

CODE:

mcc -W cpplib:libmyadd2 -T link:lib myadd2

结果,我们将会得到包含libmyadd2.dll,libmyadd2.ctf,libmyadd2.h,libmyadd2.lib等在内的一些文件。接下来我们只需要这四个文件。请注意:在MATLAB R2007b之前,这些文件都会在和编译

的m代码所在的目录中,而在MATLAB R2007b,缺省情况下这些文件会在Documents and Settings中用户的My Documents目录中。

此时,打开libmyadd2.h看看,在文件的最下面我们可以发现C++接口的函数定义。仔细观察过后,我们可以发现,这个接口函数的参数是按照这样的顺序定义的:输出参数的个数、输出参数、以及输入参数。

然后在VS2005中创建一个Win32 Console的VC++工程,我在测试时取名为testmyadd2_r2007b。把以上四个文件拷贝到VC++工程的源代码所在目录。

接下来设置VC++,让它能找到MATLAB接口函数的定义及连接库函数。可以有两种设置方式:一种是改VS2005中关于VC++的设置,这样的好处是每个新的工程都能自动获得这个设定;而另一种是只改当前工程的设置,也就是设置只对该工程有效。这里用后一种方式。

在VS2005中打开工程testmyadd2_r2007b,选择菜单“Project-->Properties,在出来的对话框上,把MATLAB提供的include路径加到VC++的头文件搜索路径。如图所示:

然后把相应的lib所在目录加到linker的额外搜索路径上。如图所示:

接下来,告诉VC++,我们的这个程序需要连接到另外两个额外的库函数:libmyadd2.lib和mclmcrrt.lib。中间用空格隔开。如图所示:

最后则是程序代码。这个程序只有一个main函数,其完整代码附在下面给大家参考。欢迎大家拍砖。谢谢!

CODE:
#include "stdafx.h"

#include 
#include "mclmcr.h"
#include "mclcppclass.h"
#include "libmyadd2.h"


int _tmain(int argc, _TCHAR* argv[])
{

       std::cout << "Hello world!" << std::endl;
       /* Initialize the MCR */ 
       if( !mclInitializeApplication(NULL,0) ) 
       { 
            std::cout << "Could not initialize the application!" << std::endl;
            return -1; 
       } 

       // initialize lib
       if( !libmyadd2Initialize())
       {
            std::cout << "Could not initialize libmyadd2!" << std::endl;
            return -1; 
       }

       try
       {
       // declare and initialize a
       mwArray a(2, 2,   mxDOUBLE_CLASS);
       double *aData;
       aData = new double[4];
       int i;
       for( i=0; i<4; ++i)
       {
            aData[i] = 1.0*i;
       }
       // print output
       std::cout << "a = " << std::endl;
       std::cout << aData[0] << ", " << aData[1] << std::endl;
       std::cout << aData[2] << ", " << aData[3] << std::endl;

       a.SetData(aData, 4);

       // declare and initialize b
       mwArray b(2, 2,   mxDOUBLE_CLASS);
       b(1,1) = 11.;
       b(1,2) = 12.;
       b(2,1) = 21.;
       b(2,2) = 22.;

       mwArray y(2, 2,   mxDOUBLE_CLASS);
       mwArray z(2, 2,   mxDOUBLE_CLASS);

       // call the function
            myadd2(2, y, z, a, b);

       // copy data from mwArray to C++ objects

       // allocate outputs
       double *yData, *zData;
       yData = new double[4];
       if( yData == NULL )
       {
            std::cout << "Failed to allocate memory for yData!" << std::endl;
            return -1;
       }

       zData = new double[4];
       if( zData == NULL )
       {
            std::cout << "Failed to allocate memory for zData!" << std::endl;
            return -1;
       }

       // copy data from mwArray to C++
       y.GetData(yData, 4);
       z.GetData(zData, 4);

       // print output
       std::cout << "y = " << std::endl;
       std::cout << yData[0] << ", " << yData[1] << std::endl;
       std::cout << yData[2] << ", " << yData[3] << std::endl;

       std::cout << "z = " << std::endl;
       std::cout << zData[0] << ", " << zData[1] << std::endl;
       std::cout << zData[2] << ", " << zData[3] << std::endl;

      
       // deallocate memory
       delete [] aData;
       delete [] zData;
       delete [] yData;
       }
       catch( const mwException& e)
       {
      std::cerr << e.what() << std::endl;
               
       }
       // terminate the lib
       libmyadd2Terminate();

       // terminate MCR
       mclTerminateApplication();


       return 0;
}
 
2007-10-6 23:18
  vs2005_matlabr2007b_result.gif  (9.26 KB) 

实验的结果表明,在C++程序中使用MATLAB编译产生的C++接口DLL非常容易。 mwArray也很容易使用。另外,最新的MATLAB R2007b中关于这部分并没有什么大的变化。这个练习适合MATLAB 7.0以后直到MATLAB R2007b的所有版本。

ask:

就我个人6.5混编的经验,我很少弄DLL,直接编译M文件为cpp,h文件即可,VC工程中引用,按.h文件格式调用即可。

这样混编基本没有任何难度,将MATLAB程序看成MFC一个类即可,看看extern里面

相关头文件的定义,跟看MSDN一样。

抛开mclTerminateApplication();这些,这应该是一个通用的办法

手头只有6.5,不知道7.5还能生成cpp么?

answer:
从matlab7.0开始,其编译器的功能就和以前版本不一样了。它不再把m代码翻译成C/C++源代码,而是对m代码作个简单的 wrapper,通常以动态链接库的形式提供给用户以方便用户在其他的程序中使用。所以,在matlab 7.x,编译m代码不能得到以前那种意义的C/C++源程序。

不过,仅从软件开发的角度来看,我觉得用DLL来打包更为方便。如果m函数的接口不变,那么每次改变m代码后,我们只需重新编译m代码,获得新的DLL及CTF,而不需要重新编译VC客户程序。这在开发大型软件时有很大的优越性。

多谢taohe的文章,我想问一下,ctf文件是干嘛用的,谢谢,记得matlab 6.5版里面编译为DLL时没这个东西啊。

这是matlab7.0以后matlab编译器的新特性。它和旧版技术不兼容。ctf其实就是一个zip文件,其中包含加密或者说编码过的一些m代码。其中有你自己的代码,以及matlab编译器通过分析你的代码根据依赖关系找到的其他一些m代码。

本文转自博客园知识天地的博客,原文链接:产生的DLL (VS2005, MATLAB7.5, mwArray),如需转载请自行联系原博主。


相关文章
|
计算机视觉 资源调度 C#
opencv通过dll调用matlab函数,图片作为参数
[blog 项目实战派]opencv通过dll调用matlab函数,图片作为参数                   前文介绍了如何“csharp通过dll调用opencv函数,图片作为参数”。而在实际的代码编写过程中,很多时候想把已经写好的matlab函数融合进去,但是依然是将图片作为参数传递比较成为问题。
1458 0
|
C++ 编译器 Windows
vs 2010调用matlab dll显示窗口核心代码
 matlab代码: figure('NumberTitle','off','menubar','none','toolbar','none','name','Topo Image'); x=0:pi/100:2*pi; y=2*exp(-0.
1355 0
|
C++
c++调用matlab生成的Dll动态连接库
点击打开链接http://download.csdn.net/detail/nuptboyzhb/4228429 c++调用matlab生成的Dll动态连接库 实验平台:   matlab 7.0(R2009a)   VC++6.0思路:1. 设置matlab的编译器,使用外部的VC或者gcc等编译器。
1661 0
|
2月前
|
安全
【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码
本文介绍了2023年高教社杯数学建模竞赛D题的圈养湖羊空间利用率问题,包括问题分析、数学模型建立和MATLAB代码实现,旨在优化养殖场的生产计划和空间利用效率。
123 6
【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码
|
2月前
|
存储 算法 搜索推荐
【2022年华为杯数学建模】B题 方形件组批优化问题 方案及MATLAB代码实现
本文提供了2022年华为杯数学建模竞赛B题的详细方案和MATLAB代码实现,包括方形件组批优化问题和排样优化问题,以及相关数学模型的建立和求解方法。
95 3
【2022年华为杯数学建模】B题 方形件组批优化问题 方案及MATLAB代码实现
|
2月前
|
数据采集 存储 移动开发
【2023五一杯数学建模】 B题 快递需求分析问题 建模方案及MATLAB实现代码
本文介绍了2023年五一杯数学建模竞赛B题的解题方法,详细阐述了如何通过数学建模和MATLAB编程来分析快递需求、预测运输数量、优化运输成本,并估计固定和非固定需求,提供了完整的建模方案和代码实现。
71 0
【2023五一杯数学建模】 B题 快递需求分析问题 建模方案及MATLAB实现代码
|
5月前
|
数据安全/隐私保护
耐震时程曲线,matlab代码,自定义反应谱与地震波,优化源代码,地震波耐震时程曲线
地震波格式转换、时程转换、峰值调整、规范反应谱、计算反应谱、计算持时、生成人工波、时频域转换、数据滤波、基线校正、Arias截波、傅里叶变换、耐震时程曲线、脉冲波合成与提取、三联反应谱、地震动参数、延性反应谱、地震波缩尺、功率谱密度
基于混合整数规划的微网储能电池容量规划(matlab代码)
基于混合整数规划的微网储能电池容量规划(matlab代码)
|
5月前
|
算法 调度
含多微网租赁共享储能的配电网博弈优化调度(含matlab代码)
含多微网租赁共享储能的配电网博弈优化调度(含matlab代码)
|
5月前
|
Serverless
基于Logistic函数的负荷需求响应(matlab代码)
基于Logistic函数的负荷需求响应(matlab代码)

热门文章

最新文章

下一篇
无影云桌面