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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361668.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

启动LINUX下的TFTP服务器

第一步: 我们要确认,LINUX下是不是安装了TFTP-SERVER. 在LINUX下输入: rpm -q tftp-server 如出现如下回复: tftp-server-0.39-2 则表示tftp-server已安装. 第二步: 修改TFTP启动脚本: 方法一: 需要修改ftptpd的启动脚本vi /etc/xinetd.d/tftp加上 disable no 此时即可启动tf…

简单代码生成器原理剖析(一)

上篇文章&#xff08;深入浅出三层架构&#xff09;分析了简单三层架构的实现。包括Model,DAL&#xff08;数据访问层&#xff09;,BLL&#xff08;业务逻辑层&#xff09;的实现。 实际开发中&#xff0c;由于重复代码的操作&#xff0c;会花费大量时间&#xff0c;如果以代码…

Qt学习之路(4):初探信号槽

看过了简单的Hello, world! 之后&#xff0c;下面来看看Qt最引以为豪的信号槽机制&#xff01;所谓信号槽&#xff0c;简单来说&#xff0c;就像是插销一样&#xff1a;一个插头和一个插座。怎么说呢&#xff1f;当某种事件发生之后&#xff0c;比如&#xff0c;点击了一下鼠标…

注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(六): 一些常用的数据库 注解...

一、 实体 Bean 每个持久化POJO类都是一个实体Bean, 通过在类的定义中使用 Entity 注解来进行声明。 声明实体Bean Entitypublic class Flight implements Serializable { Long id; Id public Long getId() { return id; } public void setId(Long id) { this.id id; }} E…

SWT鼠标单击实现

最近&#xff0c;我做了一些SWT定制小部件的开发&#xff0c;偶然发现了一个问题&#xff0c; 为什么没有默认的SWT鼠标单击侦听器&#xff1f; 由于这个主题有时会提出&#xff0c;所以我认为写一两句话来说明背后的理性基础以及如何实现鼠标单击通常不会受到伤害。 SWT鼠标请…

响应式布局笔记

一. 布局设计 固定布局&#xff1a;以像素作为页面的基本单位&#xff0c;不管设备屏幕及浏览器宽度&#xff0c;只设计一套尺寸&#xff1b; 可切换的固定布局&#xff1a;同样以像素作为页面单位&#xff0c;参考主流设备尺寸&#xff0c;设计几套不同宽度的布局。通过设别的…

麦冬

麦冬 中文学名&#xff1a;麦冬 拉丁学名&#xff1a;Ophiopogon japonicus (Linn. f.) Ker-Gawl. 别称&#xff1a;麦门冬、沿阶草 植物界百合科 主要价值&#xff1a; 1、有养阴润肺、益胃生津、清心除烦的功效&#xff0c;用于肺燥干咳、阴虚痨嗽、喉痹咽痛、津伤口渴、…

Java EE 7 / JAX-RS 2.0 – REST上的CORS

Java EE REST应用程序通常在开箱即用的开发机器上运行良好&#xff0c;该开发机器上所有服务器端资源和客户端UI均指向“ localhost”或127.0.0.1。 但是&#xff0c;当涉及跨域部署时&#xff08;当REST客户端不再与托管REST API的服务器位于同一域时&#xff09;&#xff0c;…

jQuery框架-1.jQuery基础知识

jQuery简介 jQuery&#xff0c;顾名思义是JavaScript和查询&#xff08;Query&#xff09;&#xff0c;jQuery是免费、开源的。它可以简化查询DOM对象、处理事件、制作动画、处理Ajax交互过程且兼容多浏览器的javascript库&#xff0c;核心理念是write less,do more(写得更少,…

用CornerStone配置SVN,HTTP及svn简单使用说明

原文地址&#xff1a;&#xff1a;&#xff1a;http://my.oschina.net/joanfen/blog/194491#OSC_h2_3 一、下载地址二、安装破解方法三、添加repository 1.SVN配置 2.HTTP配置四、使用简介 1.上传项目到repository 2.下载项目 3.版本管理 a)先更新后提交 b)完成独立功…

CentOS6.4 Install FTP

目录 安装参考传输模式遇到无法显示远程文件夹报错安装参考 https://www.cnblogs.com/walblog/articles/7890226.html 传输模式 主动模式被动模式遇到无法显示远程文件夹报错 点击属性设置&#xff1a; 搞定。 转载于:https://www.cnblogs.com/mysticbinary/articles/11271647.…

用于单元测试的JUnit教程–最终指南(PDF下载)

编者注&#xff1a; 我们在Java Code Geeks上提供了许多JUnit教程&#xff0c;例如JUnit入门示例 &#xff0c; 使用断言和注释的 JUnit 示例 &#xff0c; JUnit注释示例等。 但是&#xff0c;为了方便读者&#xff0c;我们希望将所有JUnit功能收集在一份详细的指南中。 我们…

EF 拉姆达 linq if else (整理)

首先想到&#xff1a;结果不正确&#xff01; var data0 db.T_Plants2; //这里加.AsQueryable()if (locationType 1){.Where(d > d.NaturalEcosystem true);}else{.Where(d > d.BuiltUpArea true);}.Select(d > new{AnimalID d.PlantID,Species d.Species,}).To…

用jOOQ用Java编写SQL

jOOQ是“数据库优先”的类型安全的SQL API&#xff0c;使您可以直观地用Java编写SQL&#xff0c;就像Java编译器本身支持SQL语言一样。 所有数据库模式&#xff0c;表&#xff0c;列&#xff0c;过程和其他对象均作为Java对象提供&#xff0c;可以直接在jOOQ SQL API中使用。 …

BizTalk开发系列(十二) Schema设计之Group与Order

更多内容请查看&#xff1a;BizTalk动手实验系列目录 BizTalk 开发系列 开发BizTalk项目的时候会先约定各系统之间往来的消息格式. 由于BizTalk内部唯一使用XML文档。因此消息的格式为XML Schema(XML Schema 用于描述 XML 文档的结构)。虽然BizTalk提供了对于XML消息的验证功能…

题解:CF1914E-Game with Marbles

题解&#xff1a;CF1914E-Game with Marbles 事先说明一下&#xff0c;本题解不讲解简单数据范围的算法&#xff0c;因为复杂数据范围的就很简单。 这道题的大体意思是这样的&#xff1a;小A有颜色为i(i1~n)的小球a[i]个&#xff0c;小B有颜色为i(i1~n)的小球b[i]个。现在他们…

【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图【强迫症福利】

标题很难引人入胜&#xff0c;先放个效果图好了 如果图片吸引不了你&#xff0c;那我觉得也就没啥看的了。 demo链接&#xff1a; https://win7killer.github.io/demo_set/html_demo/canvas/can_demo/draw_roll_2.html ************************************************* 上…

python3基础:字符串、文本文件

字符串&#xff1a; 练习1&#xff1a; str "大胖三百磅不是二百磅陪着一百磅的小胖" print(str.replace("磅", "斤")) # 替换所有 print(str.replace("磅", "斤", 2)) # 替换两次len len(str) # 这句话的字数长度 pri…

[Python][小知识][NO.3] Python 使用系统默认浏览器打开指定URL的网址

1、前言 一般用到的地方&#xff1a; GUI交互界面下&#xff0c;单击某个按钮实现打开指定网址。 某帮助菜单项目&#xff0c;需要跳转网页显示时。 O.O 某XX程序&#xff0c;需要植入网页弹窗广告时... 2、方法 调用 webbrowser 包中的 open 函数即可。 (没安装该包的 CMD命令…

MyEclipse 10优化技巧

MyEclipse 10优化速度方案仍然主要有这么几个方面&#xff1a;去除无需加载的模块、取消冗余的配置、去除不必要的检查、关闭更新。第一步: 去除不需要加载的模块一个系统20%的功能往往能够满足80%的需求&#xff0c;MyEclipse也不例外&#xff0c;我们在大多数时候只需要20%的…