[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)

MATLAB 生成 dll 前的工作

1、配置MATLAB环境

控制面板->所有控制面板项->系统->高级系统设置->高级->环境变量

Path一栏,后面追加:C:\ProgramFiles\MATLAB\R2016b\bin\win64      (32位为win32)

更改环境变量后,请重启电脑,否则VS将出现:LINK : fatal error LNK1104: 无法打开文件“libeng.lib”

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第1张图片

2、配置MATLAB中的C++编译器

在这里需要安装一个Patch,否则无法使用

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第2张图片

详细原因参考:win10系统使用vs2017 community作为matlab2016b编译器

https://blog.csdn.net/liuyingying0418/article/details/79767572

 

然后使用mex -setup 设置matlab的默认编译器,如果要生成C++语言的dll,点击mex -setup C++

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第3张图片

详细请参考链接:C/C++ VS中调用matlab函数的方法  (版本不同,操作类似)

http://blog.csdn.net/guyuealian/article/details/73743654

 

3、使用matlab生成dll

有两种方法,一种直接使用指令,一种是使用matlab的附加功能app

使用指令生成dll

如:mcc -W cpplib:TestMat64 -T link:lib Test

对应生成如下文件:

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第4张图片

这里我们只关心 TestMat64.dll  TestMat64.h  TestMat64.lib三个文件

详细参考链接:VS2015调用Matlab编译生成的DLL 编译环境设置 [吐血整理]

https://blog.csdn.net/weixin_41760829/article/details/79389685

使用matlab的附加功能app

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第5张图片

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第6张图片

这种方法跟生成exe类似,傻瓜式操作

官方参考链接 :Create a C++ Shared Library with MATLAB Code

https://ww2.mathworks.cn/help/compiler_sdk/gs/create-a-cc-application-with-matlab-code.html

 

若生成操作报错(引发的异常0xC0000005:读取位置发生访问冲突)

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第7张图片

出现这个问题的主要原因就是你Matlab文件夹下的某个工具箱访问出错,也就是你装了一个工具箱到Matlab ,并且这个工具箱会会在matlab运行的时候直接启动,这样直接导致matlab生成的dll文件中也包含了这个文件,所以直接去matlab的 安装目录下找到toolbox\local 路径删除里面的 startup.m文件,然后在重新用matlab生成一下dll文件就可以了。

详细参考链接:Matlab2016 与vs2015 混编(生成dll动态链接库) 排除编译出错

https://blog.csdn.net/qq_37469992/article/details/77575049

 

MATLAB 生成 dll 后的工作

1、配置VS2017

添加include路径:C:\Program Files\MATLAB\R2016b\extern\include

添加lib路径:C:\Program Files\MATLAB\R2016b\extern\lib\win64\microsoft

添加附加lib(附加依赖项):linker->input 追加

xxxx.lib; libmx.lib; libmat.lib; mclmcr.lib;mclmcrrt.lib;   可以只添加最后两个

xxxx.lib是自己的M文件mcc生成的,使用#pragma comment(lib,"xxxx.lib")在主cpp文件中添加

以上根据自己的路径修改

库文件不能少,否则可以看到熟悉的编译报错:error LNK2019: 无法解析的外部符号

2、函数使用

关于mwArray类的使用

mwArray类作为函数体的输入输出变量,扮演很重要的角色,在使用函数之前,务必把mwArray查清楚

https://ww2.mathworks.cn/help/compiler_sdk/cxx/mwarray.html?searchHighlight=mwArray&s_tid=doc_srchtitle

 // Create input data
 double data[] = {1,2,3,4,5,6,7,8,9};
 mwArray in1(3, 3, mxDOUBLE_CLASS, mxREAL);
 mwArray in2(3, 3, mxDOUBLE_CLASS, mxREAL);
 in1.SetData(data, 9);
 in2.SetData(data, 9);

mxArray 和 mwArray 的区别

https://blog.csdn.net/crystal_avast/article/details/7064796

函数调用过程

程序调用dll中的函数前,必须先调用xxxInitialize()这个函数,xxx指的是函数名称。程序结束时,要调用xxxTerminate()

其用于加载和卸载需要用到的dll,最后有一个判断,如

    if( !libmatrixInitialize() )
    {
        std::cerr << "Could not initialize the library properly"
                   << std::endl;
        return -1;
    }

编译运行

如果64位MATLAB生成的dll,那么VS编译目标平台也应该是x64,否则出错。

当然64位MATLAB,也可编译生成32位的dll,可以参考(不建议使用)

Build 32-bit DLL on 64-bit Windows® Platform Using MSVC Toolchain

https://ww2.mathworks.cn/help/coder/ug/build-32-bit-dll-on-64-bit-windows(r)-platform-using-msvc-toolchain.html?searchHighlight=dll&s_tid=doc_srchtitle

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第8张图片

官方示例:

https://ww2.mathworks.cn/help/compiler_sdk/cxx/integrate-a-cc-legacy-shared-library-into-an-application.html

/*==============================================================
 *
 * MATRIXDRIVER.CPP
 * Sample driver code that calls a C++ shared library created using
 * the MATLAB Compiler SDK. Refer to the MATLAB Compiler SDK
 * documentation for more information.
 *
 * Copyright 1984-2016 The MathWorks, Inc.
 *
 *============================================================*/

// Include the library specific header file as generated by the 
// MATLAB Compiler SDK
#include "libmatrix.h"

int run_main(int argc, const char **argv)
{
    if( !libmatrixInitialize() )
    {
        std::cerr << "Could not initialize the library properly"
                   << std::endl;
        return -1;
    }
    else
    {
        try
        {
            // Create input data
            double data[] = {1,2,3,4,5,6,7,8,9};
            mwArray in1(3, 3, mxDOUBLE_CLASS, mxREAL);
            mwArray in2(3, 3, mxDOUBLE_CLASS, mxREAL);
            in1.SetData(data, 9);
            in2.SetData(data, 9);
            
            // Create output array
            mwArray out;
            
            // Call the library function
            addmatrix(1, out, in1, in2);
            
            // Display the return value of the library function
            std::cout << "The value of the sum is:" << std::endl;
            std::cout << out << std::endl;
            
            multiplymatrix(1, out, in1, in2);
            std::cout << "The value of the product is:" 
                      << std::endl;
            std::cout << out << std::endl;
            
            eigmatrix(1, out, in1);
            std::cout << "The eigenvalues of the first matrix are:"
                      << std::endl;
            std::cout << out << std::endl;
        }
        catch (const mwException& e)
        {
            std::cerr << e.what() << std::endl;
            return -2;
        }
        catch (...)
        {
            std::cerr << "Unexpected error thrown" << std::endl;
            return -3;
        }     
        // Call the application and library termination routine
        libmatrixTerminate();
    }
    // mclTerminateApplication shuts down the MATLAB Runtime.
    // You cannot restart it by calling mclInitializeApplication.
    // Call mclTerminateApplication once and only once in your application.
    mclTerminateApplication();
    return 0;
}

// The main routine. On the Mac, the main thread runs the system code, and
// user code must be processed by a secondary thread. On other platforms, 
// the main thread runs both the system code and the user code.
int main(int argc, const char **argv)
{
    // Call application and library initialization. Perform this 
    // initialization before calling any API functions or
    // Compiler SDK-generated libraries.
    if (!mclInitializeApplication(nullptr, 0)) 
    {
        std::cerr << "Could not initialize the application properly"
                  << std::endl;
        return -1;
    }

    return mclRunMain(static_cast(run_main), argc, argv);
}

 

其他混编方法

调用matlab引擎

C/C++ VS中调用matlab函数的方法

https://blog.csdn.net/guyuealian/article/details/73743654

[填坑]VS2017与MATLAB2016b混合编程(生成dll方式)_第9张图片

你可能感兴趣的:(MATLAB,填坑)