Как вызвать Matlab из кода C ++? - PullRequest
3 голосов
/ 02 июля 2010

Я пытаюсь вызвать функции Matlab из кода C ++.

В Matlab приведен пример такого кода в /extern/examples/eng_mat/engdemo.cpp, однако я не нашел способа создать этот источникcode.

Вот файл сборки, который я использую:

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 ]

2 голосов
/ 03 июля 2010

Предполагая, что $ MATLABROOT - это путь к MATLAB:

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

Если вы добавите ключ -v, подробный вывод покажет вам, какие команды используются для компиляции приложения движка.

0 голосов
/ 07 июня 2014

Я решил опубликовать что-то связанное, что могло бы пригодиться кому-то, кто наткнется на этот пост в будущем, на тему вызова функции Matlab из C ++.

В учебном пособии , размещенном на сайте Mathworks, демонстрируется использование общих библиотек для вызова функций (ий) Matlab из файла C ++. Здесь команда 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 Compiler Runtime (MCR). Либо введите mcrinstaller в приглашении Matlab, либо загрузите соответствующий установщик с сайта Matlab .
  2. После этого обязательно установите LD_LIBRARY_PATH в соответствии с инструкциями в конце установщика.
  3. Текущий рабочий каталог должен быть добавлен в LD_LIBRARY_PATH. В bash я делаю это export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD

Обратите внимание, что 1 и 2 также описаны в файле readme.txt, созданном командой mcc.

0 голосов
/ 03 июля 2010

Почему вы компилируете с -static?От "man gcc":

-static В системах, которые поддерживают динамическое связывание, это предотвращает соединение с общими библиотеками.В других системах этот параметр не действует.

Другими словами, параметр -static заставляет компоновщик рассматривать только статические библиотеки, что означает, что он будет пытаться найти libmx.a вместо libmx.so.Поскольку Matlab поставляется только с общими (динамическими) библиотеками, он завершается неудачно.

Попробуйте удалить эту опцию и посмотрите, что произойдет.

Если это не сработает, вам может потребоваться запустить libtool, чтобы помочьон находит .so во время выполнения.

...