vs2013 & Matlab 2018 (64)混合编程

VS2013与Matlab 2018 64位混合编程指南

VS配置

这一步很重要,类似于其他C++库的配置,
如:添加包含目录和库路径。

  1. 添加库目录(自己的MATLAB安装路径中查找):
    在这里插入图片描述D:\Program Files (x86)\Matlab2018a\extern\include

  2. 添加库路径(自己的MATLAB安装路径中查找):

在这里插入图片描述
D:\Program Files (x86)\Matlab2018a\extern\lib\win64\microsoft

3.添加附加依赖项
在这里插入图片描述
libeng.lib
libmx.lib
libmat.lib

  1. 配置系统环境变量
    在这里插入图片描述
    在Windows环境变量中的系统变量中“Path”中新增下面三项:
    D:\Program Files (x86)\Matlab2018a\bin; (安装MATLAB后已经存在不用再添加)
    D:\Program Files (x86)\Matlab2018a\bin\win32
    D:\Program Files (x86)\Matlab2018a\bin\win64\

path配置完成后需要重启系统

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:
“无法找到libeng.dll”,等文件
经过查找libeng.dll在D:/Program Files/MATLAB/R2009a/bin/win32/下,将D:/Program Files/MATLAB/R2009a/bin/win32/加入系统的Path路径中,还是不行,后来考虑到修改Path需要重启才可以,重启以后果然可以了。

方式2调用MATLAB生成的dll

调用MATLAB生成的DLL是一种比较通用的方法,这样每次使用时只需调用这个模块就可以了。

(1)首先确认MATLAB已经完成VS配置、系统环境变量配置以及MATLAB编译器配置。
(2)将需要MATLAB完成的功能做成一个MATLAB函数。
(3)利用mcc命令编译,得到h、dll、lib等文件,在C/C++工程中只需加入上述文件即可。
(4)新建工程调用所得文件。

案例展示:
(1)首先确认MATLAB已经完成VS配置、系统环境变量配置以及MATLAB编译器配置。
在这里插入图片描述
(2)将需要MATLAB完成的功能做成一个MATLAB函数。
MATLAB函数代码

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

(3)利用mcc命令编译,得到h、dll、lib等文件,在C/C++工程中只需加入上述文件即可。
在MATLAB命令行中输入:
mcc -W cpplib:showBER-T link:lib showBER.m
得到一组文件
在这里插入图片描述
需要注意:使用 mcc -W cpplib:showBER-T link:lib showBER.m 命令编译后,需要确保编译器仍然位 “Microsoft Visual C++ 2013 ©“。
在这里插入图片描述

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

若仍然出现
在这里插入图片描述
则需要确认当前源文件的路径:
在这里插入图片描述
然后将文件复制到对应的文件夹中。

需调整解决方案平台位 x64 (与所用Matlab版本一致)
在这里插入图片描述
(4)新建工程调用所得文件。

#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链接中的介绍,亲测可用。
参考
https://blog.csdn.net/guyuealian/article/details/73743654
http://blog.163.com/rongting_chen/blog/static/164906844201252354518462/
https://www.cnblogs.com/jmliao/p/5575202.html
https://blog.csdn.net/zheng_zhiwei/article/details/49002099
转载请标明出处:C++ MATLAB 混合编程——VS项目调用MATLAB函数
文章来源: C++ MATLAB 混合编程——VS项目调用MATLAB函数

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值