加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

QT Creator与Matlab混合编程

(2013-01-14 10:23:00)
标签:

qt

matlab

分类: 编译器或软件使用

VS 2008 环境下调用matlab生成的dll

 
实验环境:
  • Win7
  • MATLAB 2009b
  • VS 2008
1.Matlab编译器设置
输入以下命令:
>> mbuild -setup
Please choose your compiler for building standalone MATLAB applications: 
 
Would you like mbuild to locate installed compilers [y]/n? n
 
Select a compiler: 
[1] Lcc-win32 C 2.4.1 
[2] Microsoft Visual C++ 6.0 
[3] Microsoft Visual C++ .NET 2003 
[4] Microsoft Visual C++ 2005 SP1 
[5] Microsoft Visual C++ 2008 Express 
[6] Microsoft Visual C++ 2008 SP1 
 
[0] None 
 
Compiler: 6
The default location for Microsoft Visual C++ 2008 SP1 compilers is C:\Program Files\Microsoft Visual Studio 9.0, 
but that directory does not exist on this machine.  
 
Use C:\Program Files\Microsoft Visual Studio 9.0 anyway [y]/n? y
 
Please verify your choices: 
 
Compiler: Microsoft Visual C++ 2008 SP1  
Location: C:\Program Files\Microsoft Visual Studio 9.0 
 
Are these correct [y]/n? y
 
**************************************************************************** 
  Warning: Applications/components generated using Microsoft Visual Studio   
           2008 require that the Microsoft Visual Studio 2008 run-time       
           libraries be available on the computer used for deployment.       
           To redistribute your applications/components, be sure that the    
           deployment machine has these run-time libraries.                  
**************************************************************************** 
 
Trying to update options file: C:\Users\Songhq\AppData\Roaming\MathWorks\MATLAB\R2009b\compopts.bat 
From template:              D:\Software\MATLAB~1\R2009b\bin\win32\mbuildopts\msvc90compp.bat 
 
Done . . . 
2.DLL生成
首先新建一个m文件,文件名为myadd2.m,定义了一个名为myadd2的函数,代码如下:
function [ y,z ] = myadd2( a,b )
%MYADD2 Summary of this function goes here
%   Detailed explanation goes here
    y=a+b;
    z=a+2*b;
end

在matlab命令窗口输入以下命令:
mcc -W cpplib:libmyadd2 -T link:lib myadd2.m
生成libmyadd2.lib, libmyadd2.h, libmyadd2.dll 等文件
3.在vs 2008环境下调用dll
3.1 新建c++ console项目

在该项目的属性中进行了配置,只对该项目有效。若建新的项目需要重新配置。项目建好后将libmyadd2.lib, libmyadd2.h, libmyadd2.dll拷贝到项目目录下。

首先配置项目属性页/配置属性/C-C++/常规/附加包含目录,请根据自己电脑上软件的安装位置对照设置,如下图所示:

http://s2/bmiddle/4dc31b56n9f9af86f54a1&690<wbr>2008 <wbr>环境下调用matlab生成的dll" TITLE="VS <wbr>2008 <wbr>环境下调用matlab生成的dll" ACTION-DATA="http://s2/bmiddle/4dc31b56n9f9af86f54a1&690" ACTION-TYPE="show-slide" STYLE="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial;" />


#SinaEditor_Temp_FontName

/链接器/常规/附加库目录,请根据自己电脑上软件的安装位置对照设置,如下图所示:

http://s9/bmiddle/4dc31b56n9f9b03ec5048&690<wbr>2008 <wbr>环境下调用matlab生成的dll" TITLE="VS <wbr>2008 <wbr>环境下调用matlab生成的dll" ACTION-DATA="http://s9/bmiddle/4dc31b56n9f9b03ec5048&690" ACTION-TYPE="show-slide" STYLE="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial;" />


3.2主程序代码

// matlabdll2.cpp : 定义控制台应用程序的入口点。

//


#include "stdafx.h"

#include <iostream>

#include <mclmcrrt.h>

#include "mclcppclass.h"

#include "libmyadd2.h"


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

{

std::cout << "Hello world!" << std::endl;

 

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] << ",\t" << aData[1] << std::endl;

std::cout << aData[2] << ",\t" << aData[3] << std::endl;

 

a.SetData(aData, 4);

std::cout<<a(1,1)<<",\t"<<a(1,2)<<std::endl;

std::cout<<a(2,1)<<",\t"<<a(2,2)<<std::endl;


// 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.;

std::cout<<b(1,1)<<",\t"<<b(1,2)<<std::endl;

std::cout<<b(2,1)<<",\t"<<b(2,2)<<std::endl;

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] << ",\t" << yData[1] << std::endl;

std::cout << yData[2] << ",\t" << yData[3] << std::endl;


std::cout << "z = " << std::endl;

std::cout << zData[0] << ",\t" << zData[1] << std::endl;

std::cout << zData[2] << ",\t" << 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;

}

运行结果:


http://s12/middle/4dc31b56n9f9b1a5a54cb&690<wbr>2008 <wbr>环境下调用matlab生成的dll" TITLE="VS <wbr>2008 <wbr>环境下调用matlab生成的dll" ACTION-DATA="http://s12/middle/4dc31b56n9f9b1a5a54cb&690" ACTION-TYPE="show-slide" STYLE="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial;" />


转自:http://blog.sina.com.cn/s/blog_4dc31b560100qp7a.html


经过好多次试验,终于在qt creator环境下成功调用matlab环境下编译的dll,步骤如下。本人的实验环境为:
  • win 7操作系统
  • matlab 2009b
  • QT Creator 2.0.1
  1. 首先在matlab环境下编译生成dll
本人用的测试函数为:
function b = myFunc(a)
%MYFUNC Summary of this function goes here
%   Detailed explanation goes here
b=a.*a;
end

首先设置编译器,关于编译器的设置在我的一篇博文中《VS 2008 环境下调用matlab生成的dll》已做阐述,在这里我们选择matlab自带的lcc编译器。

在命令行窗口输入一下命令:
mcc -t -W libhg:myfuncdll -T link:lib -h libmmfile.mlib myFunc.m
编译完成后生成myfuncdll.dll、myfuncdll.h、myfuncdll.lib等文件

可以用VC++ 6.0的depends查看工具查看生成的dll文件的export函数,如下图所示:
2.在qt creator中显式调用dll文件
  首先确定系统的环境变量中有以下几个变量:
  D:SoftwareMatlab2009R2009bruntimewin32
  D:Qt2010.05bin;
  D:Qt2010.05qtbin;
  D:Qt2010.05mingwbin;
  其中目录根据自己的安装路径所定
  
  建立一个Qt Gui Application应用,本实验取名为qttest,将刚才生成的myfuncdll.h、myfuncdll.lib拷贝至工程的qttest文件夹下,将myfuncdll.dll文件拷至运行后的debug文件夹下。

修改工程的pro文件,修改后内容如下:
#-------------------------------------------------

#

# Project created by QtCreator 2011-03-29T17:08:47

#

#-------------------------------------------------


QT += core gui


TARGET = qttest

TEMPLATE = app



SOURCES += main.cpp

mainwindow.cpp


HEADERS += mainwindow.h

libmyadd2.h

myfuncdll.h


FORMS += mainwindow.ui


OTHER_FILES +=

libmyadd2.lib

libmyadd2.dll

myfuncdll.lib

myfuncdll.dll


INCLUDEPATH += D:/Software/Matlab2009/R2009b/extern/include


INCLUDEPATH += D:/Software/Matlab2009/R2009b/extern/include/win32



LIBS+=-L D:/Software/Matlab2009/R2009b/extern/lib/win32/microsoft -llibmx

LIBS+=-L D:/Software/Matlab2009/R2009b/extern/lib/win32/microsoft -lmclmcr

LIBS+=-L D:/Software/Matlab2009/R2009b/extern/lib/win32/microsoft -lmclmcrrt



在mainwindowui上添加一个按钮,取名为显示,如下图所示:

http://s9/middle/4dc31b56n9fb429ddbaf8&690


然后进入显示按钮的clicked()槽函数,编辑完成后的mainwindow.cpp文件为:

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include 

#include 

#include 

#include 

#include 

#include 

#include "myfuncdll.h"


MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

}


MainWindow::~MainWindow()

{

delete ui;

}

typedef bool (MW_CALL_CONV *Fun)(int,mxArray**,mxArray*); //定义函数指针,以备调用

typedef bool (MW_CALL_CONV *Fun2)(void);

typedef bool (MW_CALL_CONV *Fun3)(void);

void MainWindow::on_pushButton_clicked()

{

QLibrary lib("myfuncdll.dll");

QMessageBox msg;

if(lib.load())

{

QMessageBox::information(NULL,"OK","DLL load is OK!");

Fun open=(Fun)lib.resolve("_mlfMyFunc"); //援引 _mlfMyFunc() 函数

Fun2 init=(Fun2)lib.resolve("_myfuncdllInitialize");//援引 _myfuncdllInitialize() 函数

Fun2 termi=(Fun3)lib.resolve("_myfuncdllTerminate");//援引 _myfuncdllTerminate() 函数

if (open) //是否成功连接上 add() 函数

{

QMessageBox::information(NULL,"OK","Link to Function is OK!");

init(); //库初始化

double _x[5] = {1, 2, 3, 4, 5}; //输入数组

double _y[5]; //输出数组

mxArray* x = mxCreateDoubleMatrix(1, 5, mxREAL);//创建1*5矩阵

memcpy(mxGetPr(x), (void*)_x, sizeof(_x)); //拷贝输入数据


mxArray* y = mxCreateDoubleMatrix(1, 5, mxREAL);//创建1*5矩阵

open(1,&y,x);

memcpy(_y, mxGetPr(y), sizeof(_y));//拷贝输出数据

QString song=QString::number(_y[1]);

QMessageBox::information(NULL,"OK",song);

termi();//结束DLL库

}

else

QMessageBox::information(NULL,"NO","Linke to Function is not OK!!!!");

}

else

QMessageBox::information(NULL,"NO","DLL is not loaded!");

}




3.运行结果:

http://s3/bmiddle/4dc31b56n9fb43d859142&690




http://s10/middle/4dc31b56n9fb4419bcac9&690




http://s2/middle/4dc31b56n9fb442ac2d51&690

注:在matlab环境中编译生成的头文件中的导出函数名字与在depends查看器中的名字不同,depends查看器中显示为_xxx,即在原有的函数前加了一个下划线,不知为什么,希望知道原理的高人给予指点。


l         For data conversion (scenario 1)

Include mc_convert.h and add mc_convert.cpp. Then compile.

l         For data dumping for (scenario 2)

Include matlab_dump.h and add mc_convert.cppmatlab_dump.cpp. Then compile.

 

IMPORTANCE: Define global macro HAS_OPENCV to enable openCV IplImage/CvMat conversion (e.g. properties -> C/C++ -> Preprocessor -> Preprocessor Definitions in VC environment). Current support is limited:

l         IPL_DEPTH_8U, IPL_DEPTH_32F, IPL_DEPTH_64F for IplImage conversion

l         Only Channel 1 or Channel 3 IplImage

l         Only 2D CvMat

However, it is very easy to implement (almost) full support which MIGHT be done in near future.

 IMPORTANT: Open matlab with automation mode (type "matlab /Automation" in  command line) and change disk (type cd('yourpath') in matlab) to the folder where draw_pnt.m resides before run this example. Or the example will not run normally!! 即若C/C++中调用了相关的matlab脚本或函数,一定要在运行C/C++程序前将当前使用的matlab引擎工作目录切换到调用matlab函数或脚本所在的目录!!

由于版本原因该作者源码需适当修改,如
报错:error C2766: 显式专用化;已定义“cm_traits<uint16_T>,解决方法:
是环境问题。项目属性-->配置属性-->c/C++-->语言-->将wchar_t视为内置类型 选择为 是 就可以了。
注意,我运行时出现以下错误:
Internal Error: A primary message table for module 54 was already registered with a differing collection of error messages.
在网上搜索了大量资料,如

http://www.mathworks.cn/support/solutions/en/data/1-3VR4WM/?product=CO&solution=1-3VR4WM

This error occurs because the "MATLAB" environment variable points to a different version of MATLAB than that of the MCR on the deployment machine. This causes some libraries to be dynamically loaded from a different version, and leads to this "nativeThreadRequest" error, among others.

To resolve the issue, unset the "MATLAB" environment variable, or ensure that it points to the correct version of the MCR on the deployment machine. 

但我在matlab中通过ver与mcrversion查看版本信息,并且查看生成myfuncdll.dll文件中的readme.txt文件,

发现我的matlab compiler runtime 版本与matlab版本是一致的,后来逐步调试,发现当将 myfuncdllInitialize() 函数注释掉后程序可以正常运行。经考虑可能是这个原因造成的,由于我调用了

http://www.mathworks.cn/matlabcentral/fileexchange/20927-cc++-and-matlab-types-convertor

的源码,此代码中已经开启了matlab引擎,而myfuncdllInitialize()函数则又再一次初始化引擎(此两引擎相同),引擎复用,所以报错,并且经测试发现当系统中同时打开多个matlab进程时,即使它们是同一个版本或者说同一个父亲,各matlab进程独立,包括workspace中的变量、当前目录路径等,之间没有关系影响


0

阅读 收藏 喜欢 打印举报/Report
后一篇:CUDA环境配置
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有