如何从C ++代码调用Matlab?

时间:2010-07-02 10:56:32

标签: c++ matlab g++ shared-libraries linker-errors

我试图用C ++代码调用Matlab函数。

使用Matlab,它是/extern/examples/eng_mat/engdemo.cpp中此类代码的一个示例,但是我找不到构建该源代码的方法。

这是我使用的makefile:

CFLAGS = -Wall -O3

INCLUDES = -I/opt/Matlab-2009a/extern/include

LIBRARIES = -Wl,-R/opt/Matlab-2009a/bin/glnx86 -L/opt/Matlab-2009a/bin/glnx86 -lmx -lmat -leng

out : engdemo.cpp
    g++ $(CFLAGS) $(INCLUDES) -static $^ $(LIBRARIES) -o out

clean :
    rm -f out

(这里/ opt / Matlab-2009a是我的Matlab根。)我收到这样的链接器错误:

/usr/bin/ld: cannot find -lmx
collect2: ld returned 1 exit status
make: *** [out] Error 1

问题是:如何编写g ++来编译engdemo.cpp?

请注意,共享库存在:

$ locate libmx.so
/opt/Matlab-2009a/bin/glnx86/libmx.so
/opt/Matlab-2009a/bin/glnx86/libmx.so.csf

$ ldd /opt/Matlab-2009a/bin/glnx86/libmx.so
    linux-gate.so.1 =>  (0x004b4000)
    libut.so => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libut.so (0x0078f000)
    libmwfl.so => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libmwfl.so (0x00110000)
    libicudata.so.38 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libicudata.so.38 (0xb7f82000)
    libicuuc.so.38 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libicuuc.so.38 (0x00bee000)
    libicui18n.so.38 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libicui18n.so.38 (0x001f7000)
    libicuio.so.38 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libicuio.so.38 (0x00e1c000)
    libz.so.1 => /usr/lib/libz.so.1 (0x0098e000)
    libstdc++.so.6 => /opt/Matlab-2009a/bin/glnx86/../../sys/os/glnx86/libstdc++.so.6 (0x00531000)
    libm.so.6 => /lib/libm.so.6 (0x00194000)
    libgcc_s.so.1 => /opt/Matlab-2009a/bin/glnx86/../../sys/os/glnx86/libgcc_s.so.1 (0x00eaa000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x00900000)
    libc.so.6 => /lib/libc.so.6 (0x00345000)
    librt.so.1 => /lib/librt.so.1 (0x00964000)
    libdl.so.2 => /lib/libdl.so.2 (0x0014e000)
    libexpat.so.1 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/../../bin/glnx86/libexpat.so.1 (0x00152000)
    libboost_thread-gcc42-mt-1_36.so.1.36.0 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/../../bin/glnx86/libboost_thread-gcc42-mt-1_36.so.1.36.0 (0x00fc2000)
    libboost_signals-gcc42-mt-1_36.so.1.36.0 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/../../bin/glnx86/libboost_signals-gcc42-mt-1_36.so.1.36.0 (0x0017d000)
    libboost_system-gcc42-mt-1_36.so.1.36.0 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/../../bin/glnx86/libboost_system-gcc42-mt-1_36.so.1.36.0 (0x00a06000)
    /lib/ld-linux.so.2 (0x001db000)

那么,我怎样才能使g ++编译engdemo.cpp?

3 个答案:

答案 0 :(得分:2)

假设$ MATLABROOT是MATLAB的路径:

$MATLABROOT/bin/mex -f $MATLABROOT/bin/engopts.sh engdemo.cpp

如果添加-v开关,则详细输出将显示用于编译引擎应用程序的命令。

答案 1 :(得分:0)

为什么要使用-static进行编译?来自“man gcc”:

  

<强> -static   在支持动态链接的系统上,这会阻止与共享库的链接。在其他系统上,此选项无效。

换句话说,-static选项强制链接器仅考虑静态库,这意味着它将尝试查找libmx.a而不是libmx.so。由于Matlab只附带共享(动态)库,因此失败。

尝试删除该选项&amp;看看会发生什么。

如果这不起作用,您可能需要运行libtool以帮助它在运行时找到.so。

答案 2 :(得分:0)

我认为我会发布一些可能对将来偶然发现这篇文章的人有用的东西,主题是从C ++调用Matlab函数。

在Mathworks网站上发布的tutorial中,演示了如何使用共享库从C ++文件调用Matlab函数。这里,mcc命令用于创建共享库。

随后,mbuild命令用于构建可执行文件。但是,如果你有一个复杂的C ++代码,它本身需要自己的一组共享库来进行编译,那么mbuild就不会工作了。本教程没有说明在这种情况下需要做什么。所以,我的回复的目的是发布该解决方案。用户C ++文件是vigenere.cpp,在这种情况下要链接的共享库是libvigenere.so,这是对g ++的结果调用:

g++ -o vigenere -L/usr/local/MATLAB/R2013b/runtime/glnxa64 -L. -I/usr/local/MATLAB/R2013b/extern/include/ vigenere.cpp -lmwmclmcrrt -lm -lvigenere

一些先决条件:

  1. 需要安装Matlab编译器运行时(MCR)。在Matlab提示符下键入mcrinstaller,或从Matlab site下载相应的安装程序。
  2. 执行此操作后,请务必按照安装程序末尾的说明设置LD_LIBRARY_PATH
  3. 需要将当前工作目录添加到LD_LIBRARY_PATH中。在bash中,我通过export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD
  4. 执行此操作

    请注意,mcc命令生成的readme.txt文件中也描述了1&amp; 2。