C++ MATLAB 混合编程——VS项目调用MATLAB函数DLL

标签: C++MATLAB混合编程  VS调用MATLAB函数

引言

MATLAB无疑是一款强大的矩阵运算与数据分析软件,内部集成了众多函数。如果在C++编程时可以调用相关的函数将对我们的数据分析研究带来极大的方便。这里就总结一下如何在VS工程中调用MATLAB函数,以及遇到的问题如何解决的方法。

VS配置

这一步很重要,类似于其他C++库的配置,如:添加包含目录和库路径。
添加库目录(自己的MATLAB安装路径中查找):D:\Program Files (x86)\Matlab2018a\extern\include

添加库路径(自己的MATLAB安装路径中查找):D:\Program Files (x86)\Matlab2018a\extern\lib\win64\microsoft

配置系统环境变量

在Windows环境变量中的系统变量中“Path”中新增下面三项:
D:\Program Files (x86)\Matlab2018a\bin; (安装MATLAB后已经存在不用再添加)
D:\Program Files (x86)\Matlab2018a\bin\win32;
D:\Program Files (x86)\Matlab2018a\bin\win64

MATLAB配置

在Matlab的command window输入:mex -setup
选择:mex -setup C++

然后再输入:mbuild -setup
选择:mex -setup C++ -client MBUILD

配置结束
 

测试

我们将在VS2013 的C++项目中调用MATLAB,调用方式有两种:(1)调用MATLAB引擎; (2)调用MATLAB函数生成的DLL。

方式1调用MATLAB引擎

首先,添加头文件 #include “engine.h”
然后,引用函数调用依赖库(lib) libeng.lib libmx.lib libmat.lib,之后就可以调用MATLAB引擎。

// import necessary lib
#pragma comment( lib, "libeng.lib")
#pragma comment( lib, "libmx.lib")
#pragma comment( lib, "libmat.lib")

MATLAB引擎调用和文件操作类似:打开、关闭操作。
打开引擎:

Engine *ep;  
if (!(ep = engOpen("\0")))  
{  
    fprintf(stderr, "\nCan't start MATLAB engine\n");  
    return EXIT_FAILURE;  
} 

定义变量需要转换为matlab的格式。比如使用:mxCreateDoubleMatrix 和 memcpy函数。
将数据传入引擎使用:engPutVariable()。接着调用 engEvalString(ep, “matlab指令”)matlab的指令作为参数进行操作。计算操作等完成后需要清理操作:mxDestroyArray()函数清理mxCreateDoubleMatrix 生成的变量。
engClose()关闭引擎。

完整绘图例子:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "engine.h"     // add header file

// import necessary lib
#pragma comment( lib, "libeng.lib")
#pragma comment( lib, "libmx.lib")
#pragma comment( lib, "libmat.lib")


int main(void)
{
    Engine *ep;

    // open engine
    if (!(ep = engOpen("\0")))
    {
        fprintf(stderr, "\nCan't start MATLAB engine\n");
        return EXIT_FAILURE;
    }

    // generate variables
    int Nsample = 50;
    const double PI = 3.1415926;
    double *t = new double[Nsample];

    for (int i = 0; i < Nsample; i++)
    {
        t[i] = i * 2 * PI / Nsample;
    }

    mxArray *T = NULL, *result = NULL;
    T = mxCreateDoubleMatrix(1, Nsample, mxREAL);
    memcpy((void *)mxGetPr(T), (void *)t, Nsample*sizeof(t[0]));

    engPutVariable(ep, "T", T);         // put data to engine

    // execute matlab operations
    engEvalString(ep, "Y=sin(T);");
    engEvalString(ep, "plot(T,Y);");
    engEvalString(ep, "title('y=sin(t)');");
    engEvalString(ep, "xlabel('t');");
    engEvalString(ep, "ylabel('y');");

    printf("Hit return to continue\n");
    fgetc(stdin);

    // clean operation(don't forget!!!)
    mxDestroyArray(T);
    engEvalString(ep, "close;");

    // close engine
    engClose(ep);

    return EXIT_SUCCESS;
}

效果:

出现错误解决方法:

1>------ 已启动生成:  项目: CMatlab, 配置: Debug Win32 ------
1>main.obj : error LNK2019: 无法解析的外部符号 _mxGetPr_800,该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 _mxDestroyArray_800,该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 _mxCreateDoubleMatrix_800,该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 _engEvalString,该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 _engOpen,该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 _engClose,该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 _engPutVariable,该符号在函数 _main 中被引用
1>E:\shizhenwei\VS2013Projects\CMatlab\Debug\CMatlab.exe : fatal error LNK1120: 7 个无法解析的外部命令

这个问题出在兼容上。我们需要将vs工程变为64位,然后即可解决。

方式2调用MATLAB生成的DLL

调用MATLAB生成的DLL是一种比较通用的方法,这样每次使用时只需调用这个模块就可以了。
首先,将需要MATLAB完成的功能做成一个MATLAB函数。
然后,利用mcc命令编译,得到h、dll、lib等文件,在C/C++工程中只需加入上述文件即可。

MATLAB函数代码

function showBER(SNR_indB,BER)
semilogy(SNR_indB,BER,'-o','linewidth',2);
grid on
xlabel('E_b/N_0(dB)');
ylabel('BER');

编译后,在MATLAB命令行中输入:

mcc -B csharedlib:showBER showBER.m

得到一组文件

将其中的.dll .h .lib文件拷贝到C工程中,在需要调用绘图模块的cpp文件中加入如下代码:

#include "showBER.h"

#pragma comment( lib, "libeng.lib" )
#pragma comment( lib, "libmx.lib" )
#pragma comment( lib, "libmat.lib" )
#pragma comment( lib, "mclmcrrt.lib" )
#pragma comment( lib, "showBER.lib" )

void main(void)
{
    double SNR[] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5 };
    double BER[] = { 9.728816e-002, 8.099609e-002, 5.633803e-002, 3.733608e-002, 1.253970e-002, 3.936489e-003, 1.206820e-003, 2.104052e-004, 3.109879e-005, 3.365857e-006, 2.565067e-007 };
    int len = sizeof(SNR) / sizeof(SNR[0]);

    showBERInitialize();

    mxArray* xSNR = mxCreateDoubleMatrix(1, len, mxREAL);
    memcpy(mxGetPr(xSNR), (void*)SNR, sizeof(SNR));
    mxArray* xBER = mxCreateDoubleMatrix(1, len, mxREAL);
    memcpy(mxGetPr(xBER), (void*)BER, sizeof(BER));

    mlfShowBER(xSNR, xBER);
    system("PAUSE");

    showBERTerminate();
}

运行效果

提示

其他打包方法可以参考3和4链接中的介绍,亲测可用。

参考
C/C++ VS中调用matlab函数的方法_vs调用matlab函数_AI吃大瓜的博客-CSDN博客
http://blog.163.com/rongting_chen/blog/static/164906844201252354518462/
https://www.cnblogs.com/jmliao/p/5575202.html
64位系统vs2010平台下实现C++与matlab R2014混合编程方法示例_add exported functions_Jerry-1990的博客-CSDN博客

版权声明:本文为wokaowokaowokao12345原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:C++ MATLAB 混合编程——VS项目调用MATLAB函数_c++调用matlab引擎_大作家佚名的博客-CSDN博客

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
目录 第1章 matlab概述. 1.1 matlab的发展历程 1.2 matlab产品组成及语言特点 1.2.1 matlab的主要产品构成 1.2.2 matlab语言的特点 1.3 matlab 7.0的新功能和新产品 1.3.1 matlab 7.0的新功能 1.3.2 matlab升级及新增的模块 1.4 小结 第2章 matlab程序设计及代码优化 2.1 matlab的表达式和变量 2.1.1 表达式 2.1.2 变量 2.2 细胞数组与结构数组 2.2.1 细胞数组 2.2.2 结构数组 2.3 类与对象 2.4 流程控制 2.4.1 for循环结构 2.4.2 while循环结构 .2.4.3 if-else-end分支结构 2.4.4 switch-case结构 2.4.5 try-catch结构 2.5 m文件编程 2.6 m文件编程规范 2.7 m文件评述器 2.8 提高m文件执行效率的技巧 2.8.1 矢量化操作 2.8.2 给数组预定义维 2.8.3 下标或者索引操作 2.8.4 尽量多使用函数文件而少使用非脚本文件 2.8.5 将循环体中的内容转换为c-mex 2.8.6 内存优化 2.9 小结 第3章 matlab混合编程简介 3.1 进行混合编程的出发点 3.2 matlab应用程序接口简介 3.3 几种常见的混合编程方法简介 3.3.1 使用matlab自带的matlab compiler 3.3.2 利用matlab引擎 3.3.3 利用activex控件 3.3.4 利用mat文件 3.3.5 c-mex 3.3.6 利用mideva/matcom 3.3.7 利用matrix[lib]实现混合编程 3.3.8 利用matlab add-in 3.3.9 matlab com builder 3.3.10 matlab和excel混合编程 3.4 小结 第4章 c-mex编程 4.1 c-mex简介 4.2 mex文件系统的配置 4.3 mex文件的结构和运行 4.3.1 mex文件结构 4.3.2 mex函数的执行流程 4.3.3 mex文件的结构和使用 4.3.4 mex文件与独立应用程序的区别 4.4 c语言mex函数 4.5 c-mex混合编程 4.6 visual c++中mex文件的建立和调试 4.6.1 visual c++中mex程序的建立和环境设置 4.6.2 mex程序的调试 4.6.3 mex独立应用程序的发布 4.7 mex编程实例 4.8 小结 第5章 通过matlab引擎实现混合编程 5.1 matlab引擎简介 5.2 matlab引擎库函数 5.3 visual c++调用matlab引擎时的环境设置 5.4 matlab引擎类的封装 5.4.1 cmatlabeng类的定义和实现代码 5.4.2 cmatlabeng说明 5.4.3 cmatlabeng说明和使用方法 5.5 应用实例 5.6 小结 第6章 mat文件实现数据共享 6.1 mat文件简介 6.2 操作mat文件 6.2.1 mat文件格式 6.2.2 操作mat文件的matlab api 6.3 visual c++调用mat时的环境设置 6.4 实例 6.5 小结 第7章 利用mideva实现混合编程 7.1 mideva简介 7.2 mideva的安装 7.3 mideva环境下m文件到dll/exe文件的转换 7.4 visual c++环境下使用mideva混合编程 7.4.1 混合编程环境的设置 7.4.2 通过外壳函数调用 7.5 matrix[lib] 7.6 混合编程实例 7.7 小结 第8章 利用matrix[lib]实现混合编程 8.1 matrix[lib]简介 8.2 matrix[lib]与visual c++混合编程 8.2.1 matrix[lib]的安装 8.2.2 visual c++环境配置 8.2.3 初始化库 8.3 matrix[lib]函数使用参考 8.3.1 矩阵操作 8.3.2 库常量 8.3.3 访问库函数 8.3.4 矩阵i/o 8.3.5 图形函数 8.4 混合编程实例 8.5 matlab数学库 8.5.1 简介 8.5.2 visual c++工程中调用matlab数学函数库的环境设置 8.6 小结.. 第9章 通过matlab add-in实现混合编程 9.1 matlab add-in简介 9.2 matlab add-in安装和在visual c++中的环境设置 9.3 通过matlab add-in生成独立应用程序 9.4 matlab add-in实例 9.5 小结 第10章 matlab和delphi混合编程 10.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值