Matlab与C++实现双向调用

一、ZeroICE框架的局限性

        ICE提供的Python、C++示例代码均可实现客户端同服务端的双向调用,唯独Matlab仅提供了单项调用。

 

  • 解决思路

        ICE不提供,那就只好曲线救国了。在我的概念里,没有啥是不能通过增加一层来解决问题的。        

        这个框架就变成了Matlab与C++的混合编程问题了

 

        为了便于Matlab开发人员使用,那么调试的IDE必须是Matlab环境,最好的方式是将C++客户端这一层作为dll存在,在Matlab中加载,以下是调用思路

 

二、实施

1.Matlab加载C dll,增加main.m

        实现C库的加载,及调用C库中提供的run函数

function main()

    if not(libisloaded('run'))

        loadlibrary('run','run.h')

    end


    calllib('run','run')

    unloadlibrary('run')

end

        loadlibrary('run',“run.h”)

        这种写法需要加上函数导出对应的头文件,详细说明请参考:
将 C 共享库加载到 MATLAB - MATLAB loadlibrary- MathWorks 中国此 MATLAB 函数 将头文件 hfile 中定义的 C 共享库 libname 中的函数加载到 MATLAB 中。loadlibrary 函数仅支持可从 C 语言环境中调用的调用函数,以及可由 C 编译器解析的头文件。采用 C++ 语言编写的函数必须声明为 extern C。或者,要调用 C++ 库中的函数,请参阅 MATLAB 中的 C++ 库。icon-default.png?t=LBL2https://ww2.mathworks.cn/help/matlab/ref/loadlibrary.html

         matlab调动dll库中的函数

调用 C 共享库中的函数 - MATLAB calllib- MathWorks 中国此 MATLAB 函数 调用 C 库 libname 中的函数 funcname,从而传递输入参数 arg1,...,argN。calllib 函数返回从 x1,...,xN 中的 funcname 获得的输出值。icon-default.png?t=LBL2https://ww2.mathworks.cn/help/matlab/ref/calllib.html?searchHighlight=calllib&s_tid=srchtitle_calllib_1

2.将main.m编译成exe,实现加载dll库

        在matlab中调试,以上这种加载方式没问题,但如果要把.m编译成exe,那就要用到loadlibrary(libname,@protofile)这种模式加载动态库,否则编译会出错。

        1).将C的动态库,转为matlab可加载的原型库

                loadlibrary('run','run.h','mfilename','run')

                这时matlab会生成新的命名为run_thunk_pcwin64.dll文件

        2).将之前的加载方式改为

                loadlibrary('run',@run)

                这样就可以顺利的编译exe了

         3).编译成exe时,一定要把新生成的动态库包含进来

                mcc -m main.m -a ./run_thunk_pcwin64.dll

3.添加matlab的回调函数,比如add

function c=add(a,b)

c=a+b;

end

4.C代码中run的实现

        这里采用matlab提供的c的方式调用matlab引擎,必须安装matlab开发环境,如果只有运行环境,没有matlab的开发环境,是无法工作的。

        matlab提供了多种调用方式,对于C++调用方式,我没有调通,如果有同学调通可以告知下,非常感谢!

//头文件需要指向matlab安装目录D:\Program Files\MATLAB\R2017b\extern\include

//需要的matlab动态库libeng.lib;libmx.lib;

//编译时链接库的目录D:\Program Files\MATLAB\R2017b\extern\lib\win64\microsoft

#include "mex.h"

#include "engine.h"



int run()

{

    Engine* ep;

    if (!(ep = engOpen(NULL))) {

        fprintf(stderr, "\nCan't start MATLAB engine\n");

        return EXIT_FAILURE;

    }


    //这里需要将add.m的路径增加进来,userpath是更改当前路径,效率更高;addpath是将路径添加到系统的搜索路径中来,二选一,否则matlab是无法找到你自己写的函数的。

    //engEvalString(ep, "userpath('D:\\Test');");

    engEvalString(ep, "addpath('D:\\Test');");



    //回调matlab中我们自己实现的add函数

        a = mxCreateDoubleMatrix(1, 1, mxREAL);

        b = mxCreateDoubleMatrix(1, 1, mxREAL);

        *mxGetPr(a) = 10;

        *mxGetPr(b) = 20;

        engPutVariable(ep, "a", a);

        engPutVariable(ep, "b", b);

    //这里有多种调用方式,请参考总结中给出的官网链接,不同调用方式其效率还是有很大不同,这里用户可以自己去测试

        engEvalString(ep, "c = add(a,b);");

        c = engGetVariable(ep, "c");

        ret = mxGetPr(c) ;

        std::cout << "C=" << *ret << std::endl;

}

三、总结

        这种matlab与C++双向调用的方式网上资料很少,多数讲的都是单项如何调用,虽然用引擎的方式可以实现,但这似乎并不是最优解,还未能脱离matlab的开发环境,如果能够实现仅在matlab的运行环境下使用,会更好,我们在持续探索,如果有新的进展会发布出来,希望能对大家有用!

Matlab扩展语言接口:外部语言接口- MATLAB & Simulink- MathWorks 中国icon-default.png?t=LBL2https://ww2.mathworks.cn/help/matlab/external-language-interfaces.html?s_tid=CRUX_lftnav

C代码中调用matlab函数的方式:Callbacks in Applications- MATLAB & Simulink- MathWorks 中国icon-default.png?t=LBL2https://ww2.mathworks.cn/help/matlab/matlab_external/gui-intensive-applications.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值