from: http://www.simwe.com/forum/thread-801187-1-1.html

程序中使用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++的头文件搜索路径。如图所示:

 vs2005_matlabr2007b_inc01.gif (25.26 KB)

然后把相应的lib所在目录加到linker的额外搜索路径上。如图所示:
 vs2005_matlabr2007b_lib01.gif (25.99 KB)

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

最后则是程序代码。这个程序只有一个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代码。

转载于:https://www.cnblogs.com/mfryf/archive/2012/02/16/2354285.html

产生的DLL (VS2005, MATLAB7.5, mwArray)相关推荐

  1. 创建在Linux上运行的 .NET Core 应用程序(matlab封装的dll文件)

    matlab社区:https://ww2.mathworks.cn/help/releases/R2019b/compiler_sdk/dotnet/create-a-dotnet-core-appl ...

  2. 【转载】Matlab与C#连接的几种方式比较

    引自:   http://hi.baidu.com/adda/blog/item/c19bd33f3d87a6c77d1e714f.html 使用环境 Visual Studio 2005,Matla ...

  3. vc++ 2005 发布程序

    目前 硬件配置在提高,软件开发环境也在不停的升级,vs2008 beta2 Enterprise Edition已经发布,使用的结果感觉非常满意,比vs2005进步不少,首先在IDE环境的启动速度上比 ...

  4. VS2017的C#语言与matlab2014A的m语言混合编程的方法

    VS2017的C#语言与matlab2014A的m语言混合编程的方法 摘要: 有两种方法能够实现C#语言调用matlab编写的函数:一种是利用matlab应用类型库直接调用matlab函数:另一种是将 ...

  5. WM6天气预报程序的开发

    去年换了个智能手机,虽然很山寨,但是还蛮喜欢的.不停的刷机,装各种软件,从WM5到WM6,熟悉之后,就没了新鲜感,感觉电话吗,也就是个电话,老折腾这个干嘛.但是确实离不了了,跟LP换了一段手机使用,那 ...

  6. VS2005发布、生成网站时如何设置固定的dll文件名?

    在用VS2005发布网站项目时,默认生成bin目录下的.dll文件名是随机命名的; 如果要固定生成文件名如何固定呢?有以下两种方案: 一.每个页面的程序集分别生成对应的dll; 方法:在"发 ...

  7. AjaxPro.2.dll在VS2005使用中的基本使用

    个人常用的东西收集起来,也给大家一起分享哈.AjaxPro.2.dll在VS2005使用中的基本使用,下面介绍了基本的配置和最简单的使用方法 AJAX不用说大家都明白,不明白的请百度或Google一下 ...

  8. VS2005下如何新建一个WINCE设备的DLL工程

    一.       动态链接库简介 1.1 DLL概述 动态链接库(Dynamic Link Library, j简称DLL)是一些编译过的可执行的程序模块,可以在应用程序中或其他DLL中被调用.DLL ...

  9. 当引用com类dll时,在VS2005下会出现,dll虽然更换了但是引用没有更换或找不到的错误

    当引用com类dll时,在VS2005下会出现,dll虽然更换了但是引用没有更换或找不到的错误 处理办法: 打开*.vbProj文件找到最后一个<ItemGroup>,添加或更改<C ...

最新文章

  1. ESXi6.5环境搭建(三:vSphere Client6.0安装)
  2. 零基础Java学习之抽象类
  3. spring-boot项目打包时候出现boot-inf文件夹的问题
  4. FCC有意支持Sprint与T-Mobile合并?
  5. js 格式化日期 (/Date(1400046388387)/)
  6. 第2节 mapreduce深入学习:12、reducetask运行机制(多看几遍)
  7. (02)System Verilog 程序块结束仿真
  8. listView使用checkBox的实现
  9. 多目标追踪综述阅读(2021)
  10. c++ 位运算 和 掩码
  11. 为什么华为,腾讯,阿里等大公司都有外包员工?
  12. 百度冰桶算法2.0简介
  13. java faker_小飞博客-java测试造数据神器JavaFaker
  14. 基于数据kmeans_data分析聚类画图 使用sc轮廓系数作为评价指标
  15. Educoder/头歌JAVA实训——JAVA面向对象:类与对象
  16. php只获取年月日,php怎么实现date只显示年月日
  17. java 自然常数e中出现的连续的第一个10个数字组成的质数_冷知识:数学常数“e”的传奇故事...
  18. 谢尔盖·布林给Google Glass开发者的的一封信
  19. server接收dtu透传代码_深入ASP.NET Core源代码之 - Web Server Kestrel
  20. Adobe Flash Builder 4.5的安装

热门文章

  1. linux镜像文件不要大于4g,Systemback制做大于4G的Ubuntu系统镜像
  2. C |格式化输出与变量类型
  3. C/C++制作人机猜拳小游戏
  4. pannel添加的子窗体很大_超简单的地瓜粉焖子做法全解,零失败
  5. 反射-获取java私有内部类反射类型、私有字段
  6. 光模块常见故障与使用注意事项详解
  7. [渝粤教育] 西北工业大学 博弈论基础 参考 资料
  8. 【渝粤题库】广东开放大学 商务翻译实务 形成性考核
  9. 【渝粤题库】陕西师范大学152206领导科学 作业(高起专、专升本)
  10. input不可编辑属性_谁不喜欢图文并茂呢:基于多模态信息的属性抽取