VC6.0与matlab混合编程( 脱离matlab运行环境)方法
来源:互联网 发布:金蝶软件标准版教程 编辑:程序博客网 时间:2024/05/19 13:31
这篇文章是我综合了几篇主流的方法汇总的。由于最近需要VC与matlab混合编程,但在参考了许多教程后,发现总会有一些这样或那样的问题导致不能够正常使用。本文是建立在别人的基础上修改而来的原文参见:。
增添了1)出现Warning : No matching builtin function available 。。。 和 Undefined command/function 'set_param'
的报错情况
1、 Matlab7.0 编译器设置
(1) mex 命令设置
(a) 运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入“ mex -setup ”命令后,按回车键,安装 Matlab 编译器;
(b) 命令窗口出现如下提示:
Please choose your compiler for building external interface (MEX) files:
Would you like mex to locate installed compilers [y]/n?
此时键入 ”y” ,按回车;
(c) 命令窗口出现如下提示:
Please choose your compiler for building external interface (MEX) files:
Would you like mex to locate installed compilers [y]/n? y
Select a compiler:
[1] Digital Visual Fortran version 6.0 in C:/Program Files/Microsoft Visual Studio
[2] Lcc C version 2.4 in C:/MATLAB6P5/sys/lcc
[3] Microsoft Visual C/C++ version 6.0 in C:/Program Files/Microsoft Visual Studio
[0] None
此时键入 ” 3” ,按回车 ;选择 Microsoft Visual C++6.0 的编译器
(d) 命令窗口出现如下提示:
Please verify your choices:
Compiler: Microsoft Visual C/C++ 6.0
Location: C:/Program Files/Microsoft Visual Studio
Are these correct?([y]/n):
此时键入 ”y” ,按回车 ;确认选择 Microsoft Visual C++6.0 的编译器
(2) mbuild 命令设置
(a) 运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入“ mbuild -setup ”命令后,按回车键,安装 Matlab 编译器;
(b) 命令窗口出现如下提示:
Please choose your compiler for building standalone MATLAB applications:
Would you like mbuild to locate installed compilers [y]/n?
此时键入 ”y” ,按回车 ;
(c) 命令窗口出现如下提示:
[1] Lcc C version 2.4 in C:/MATLAB6P5/sys/lcc
[2] Microsoft Visual C/C++ version 6.0 in C:/Program Files/Microsoft Visual Studio
[0] None
此时键入 ” 2” ,按回车 ;选择 Microsoft Visual C++6.0 的编译器
(d) 命令窗口出现如下提示:
Please verify your choices:
Compiler: Microsoft Visual C/C++ 6.0
Location: C:/Program Files/Microsoft Visual Studio
Are these correct?([y]/n):
此时键入 ”y” ,按回车 ,确认选择 Microsoft Visual C++6.0 的编译器,编译器设置完成。
2 、编写 Matlab 函数
函数文件 sum_prod.m ,内容如下:
function [sum,prod] = sum_prod(p1,p2)
sum = p1+p2; % p1 与 p2 的和
prod = p1.*p2; % p1 与 p2 的点乘
该函数完成的是矩阵的求和与点乘的功能,下面将介绍把该代码转换成 VC++ 环境可用的代码的方法。
3、将 Matlab 函数转成 DLL 函数
在 Matlab7.0 的 Command Window 下输入命令 :
命令 1 : mcc -W lib:libsum_prod -T link:lib sum_prod.m
或
命令 2 : mcc -W cpplib:libsum_prod -T link:lib sum_prod.m
生成动态链接库 DLL ,编译完成后, Matlab 生成一些文件, 其中
libsum_prod.ctf
libsum_prod.dll
libsum_prod.h
libsum_prod.lib
这些文件是我们后面需要用到的。
特别注意 : 1)命令 1 生成的 DLL 函数接口的数据类型是 mxArray ,命令 2 生成的 DLL 函数接口的数据类型是 mwArray 。
mxArray可认为是C中与Matlab中相对应的矩阵类型。在C中,变量需要先定义,后使用。另外,在定义mxArray类型的变量后,需要对其进行初始化,指定它的类型和尺寸。mxGetPr()函数用于获取mxArray类型数据的实部首地址,因为内存是连续分配的,所以可以使用内存拷贝函数将一个数组的数据拷贝给它
2)转化时可能遇到的问题
7.0/7.1版本有个问题:
Warning : No matching builtin function available for D:\matlab\install\toolbox\simulink\simulink\set_param.bi
或者mcc变成m文件成可执行文件exe后,运行会出现:
Undefined command/function 'set_param' Warning : No matching builtin function available
Error in ==> matlabrc at 81
解决方法:
1、将D:\matlab\toolbox\compiler\deploy\matlabrc.m 中的
81行 set_param(0,'PaperType',defaultpaper);
82行 set_param(0,'PaperUnits',defaultunits);
注释掉,或者干脆删掉。
2、在Matlab的命令窗口运行rehash toolboxcache
3、重新编译文件后即可运行。
4 、 VC++6.0工程的创建与设置
(1) 建立一个名为 Test 的 C++ 控制台工程,在工程中添加一个名为 Test.cpp 文件
(2) 对 VC ++ 6.0 ,进行以下设置
单击菜单 Tools ,出现如下菜单
单击 Options… 菜单项,出现 Options 对话框,选择 Directories 标签,在 include files 里面加入:
C:/MATLAB7/EXTERN/INCLUDE
如下图所示
在 Library files 里面加入:
C:/MATLAB7/EXTERN/LIB/WIN32/MICROSOFT/MSVC60
如下图所示
(3) 对该工程,进行以下设置
单击菜单 Project ,出现如下菜单
单击 Setting… 菜单项,出现 Project Setting 对话框,选择 Link 标签,在 Object/library modules: 下面的文本框内容的后面加入 mclmcrrt.lib libsum_prod.lib ,如下图所示
5 、代码编辑及 DLL 调用
(1) 将前面生成的四个文件:
libsum_prod.ctf
libsum_prod.dll
libsum_prod.h
libsum_prod.lib
复制到 VC 工程所在目录。
(2) 在 VC ++ 6.0 环境中, 单击菜单 Project , 选择 Add to Project 菜单项,再单击 Files… 子菜单项,出现如下图对话框,
将 libsum_prod.h 加入到当前工程中。
(3) 当用命令 1 生成的 DLL 函数时 ,在工程文件 Test.cpp 中添加以下代码:
#include "iostream.h" // 输入输出头文件
#include "mclmcr.h" // mxArray 类型声明
#include "libsum_prod.h" // DLL 头文件
void display(const mxArray* in, const char* name);
int main()
{
// 初始化程序
if( ! mclInitializeApplication(NULL,0) )
{
fprintf(stderr, "Could not initialize the application./n");
exit(1);
}
// 初始化库
if (! libsum_prodInitialize() )
{
fprintf(stderr,"Could not initialize the library./n");
exit(1);
}
// 声明 DLL 函数输入输出 mxArray 对象
mxArray *X,*Y;
mxArray *SUM=NULL,*PROD=NULL;
// 给输入 mxArray 对象分配内存
X = mxCreateDoubleMatrix(2,3,mxREAL);
Y = mxCreateDoubleMatrix(2,3,mxREAL);
double x[] = {1,2,3,4,5,6};
double y[] = {7,8,9,10,11,12};
// 给输入 mxArray 对象赋值
memcpy(mxGetPr(X),x,6*sizeof(double));
memcpy(mxGetPr(Y),y,6*sizeof(double));
// 调用 DLL 函数,注意输入与输出的接口是不同的
mlfSum_prod(2,&SUM,&PROD,X,Y) ;
// 显示 mxArray 对象
display(SUM,"SUM");
display(PROD,"PROD");
// 释放输入输出 mxArray 对象所占用的内存
// 注意输出对象的内存是在调用 DLL 函数过程中分配的
mxDestroyArray(X);
mxDestroyArray(Y);
mxDestroyArray(SUM);
mxDestroyArray(PROD);
// 关闭库和程序
libsum_prodTerminate() ;
mclTerminateApplication() ;
return 0;
}
// 显示矩阵函数
void display(const mxArray* in, const char* name)
{
int i,j,r,c;
double *data;
data = mxGetPr(in);
r = mxGetM(in);
c = mxGetN(in);
printf("%s = /n",name);
for(i=0;i<r;i++)
{
printf("/t");
for(j=0;j<c;j++)
printf("% 4.2f /t",data[j*r+i]);
printf("/n");
}
printf("/n");
}
该 C++ 程序运算结果如下图所示
(4) 当用命令 2 生成的 DLL 函数时 ,在工程文件 Test.cpp 中添加以下代码:
#include "iostream.h" // 输入输出头文件
#include "mclmcr.h" // mwArray 类型声明
#include "libsum_prod.h" // DLL 头文件
void display(const double* data, const int r, const int c, const char* name);
int main()
{
// 初始化程序
if( ! mclInitializeApplication(NULL,0) )
{
fprintf(stderr, "Could not initialize the application./n");
exit(1);
}
// 初始化库
if (! libsum_prodInitialize() )
{
fprintf(stderr,"Could not initialize the library./n");
exit(1);
}
// 声明 DLL 函数输入输出 mwArray 对象
mwArray X(2,3,mxDOUBLE_CLASS);
mwArray Y(2,3,mxDOUBLE_CLASS);
mwArray SUM,PROD;
double x[] = {1,2,3,4,5,6};
double y[] = {7,8,9,10,11,12};
double *sum,*prod;
sum = new double[6];
prod = new double[6];
// 给输入 mwArray 对象赋值
X.SetData(x,6);
Y.SetData(y,6);
// 调用 DLL 函数
sum_prod(2,SUM,PROD,X,Y) ;
// 取出输出数据
SUM.GetData(sum,6);
PROD.GetData(prod,6);
// 显示 mwArray 对象
// std::cout << "SUM = " << std::endl << SUM << std::endl;;
// std::cout << "PROD = " << std::endl << PROD << std::endl;;
display(sum,2,3,"SUM");
display(prod,2,3,"PROD");
delete sum;
delete prod;
// 关闭库和程序
libsum_prodTerminate() ;
mclTerminateApplication() ;
return 0;
}
// 显示矩阵函数
void display(const double* data, const int r, const int c, const char* name)
{
int i,j;
printf("%s = /n",name);
for(i=0;i<r;i++)
{
printf("/t");
for(j=0;j<c;j++)
printf("% 4.2f /t",data[j*r+i]);
printf("/n");
}
printf("/n");
}
该 C++ 程序运算结果如下图所示
特别说明:
在 C/C++ 环境中二维数组是“行向量” ,如果将下面定义的变量 x 看成二维数组的话
double x[] = {1,2,3,4,5,6};
那么 x 应该是 的矩阵,即
x = [1,2,3;
4,5,6];
但是,如果将数组首地址 x 初始化 mxArray 和 mwArray 类时, 数组 x 在 mxArray 和 mwArray 类中是按“列向量”的形式排列 的,即
X = [1,3,5;
2,4,6];
同理,这里
Y = [7,9,11;
8,10,12];
因此才能得到上图的结果
6 、脱离matlab运行环境发布
如果仅是在本机上使用DLL,那么以上六步即可满足要求。如果要在没有安装Matlab的计算机中使用此DLL,还需要随DLL拷贝一些动态链接库等文件。双击D:\MATLAB6p5p1\extern\lib\win32文件夹下的mglinstaller.exe文件,即可生成所需的文件。mglinstaller.exe会在D:\MATLAB6p5p1\extern\lib\win32文件夹下生成两个新的文件夹,它们的名称分别是bin和toolbox。发布时只要把这两个文件夹连同DLL一起拷贝就可以了。所需要文件数目是很大的,但应该可以。
- VC6.0与matlab混合编程( 脱离matlab运行环境)方法
- matalb7与VC2008混合编程DLL方法(四)脱离matlab和VC环境的运行和程序发布
- matlab 7与vc/mfc混合编程 脱离运行环境,移植代码
- 让matlab程序脱离matlab环境运行
- 浅谈VC6.0和Matlab混合编程之Matlab引擎
- 脱离matlab环境,在VC种运行
- matlab与c混合编程实现方法
- Matlab与VC6.0的环境配置
- Java与Matlab混合编程环境配置与实例分析
- MATLAB 与C混合编程:通过mex提高运行速度
- VC环境和Matlab混合编程的实现方法
- Matlab与VC混合编程
- Matlab与VC混合编程
- vc与matlab混合编程
- Matlab与VC混合编程
- Matlab与VC混合编程
- matlab与c++混合编程
- VB与Matlab混合编程
- Service自启动注意的事项
- 升武器论的终结
- 天梯匹配规则ELO
- Ubuntu更改文件夹权限
- 基本数据类型包装类
- VC6.0与matlab混合编程( 脱离matlab运行环境)方法
- VSS设置默认登录用户
- VC中使用GetModuleFileName获取应用程序路径(整理)
- 日省其身,有则改之,无则加勉!
- 【Android应用开发】-(23)Android SIP 支持
- Codeforces-134D2A
- P2P协议与P4P协议
- _CrtSetBreakAlloc
- java.lang.reflect.InvocationTargetException