Преобразование библиотеки C ++ в MATLAB mex

0

У меня большой C++ код, и я хочу интегрировать его в MATLAB, чтобы я мог использовать его внутри моего кода matlab. Если бы это был единственный код, делающий его mex файл лучшим вариантом. Но так как теперь это код, который нужно скомпилировать и построить для запуска, я не знаю, как использовать функции в этом коде.
Является ли создание файлов mex для всего кода единственным вариантом или есть ли какое-либо другое обходное решение? Также мне нужна помощь в том, как я могу создавать файлы mex для всего кода, а затем создавать его.

Для более глубокого понимания это код, который я пытаюсь интегрировать в matlab http://graphics.stanford.edu/projects/drf/densecrf_v_2_2.zip. Спасибо!

  • 0
    Мекс-функции не помогут, поскольку они не допускают программирования классов и объектов. Мое предложение было бы перевести на управляемый язык .NET, такой как C #. Вы можете использовать код напрямую через NET.addAssembly() . Затем у вас будет код, который работает внутри и вне MATLAB. Смотрите информацию по этой ссылке: mathworks.com/help/matlab/using-net-libraries-in-matlab.html
  • 2
    @Juderb: было бы много работы по переносу библиотеки с C ++ на C #, не говоря уже о том, что вы потеряете все виды оптимизации (вышеупомянутая библиотека с использованием инструкций SSE и тому подобное)! MATLAB легко позволяет использовать внешние библиотеки с помощью MEX-функций
Показать ещё 1 комментарий
Теги:
integration
mex

2 ответа

3
Лучший ответ

Сначала вам нужно скомпилировать библиотеку (статическую или динамически связанную). Вот шаги, которые я предпринял на своей машине Windows (у меня есть Visual Studio 2013 как C++ компилятор):

  • Создайте файлы проекта Visual Studio с помощью CMake, как описано в файле README.
  • запустить VS и скомпилировать densecrf.sln решения densecrf.sln. Это приведет к созданию статической библиотеки densecrf.lib

Затем измените пример файла dense_inference.cpp чтобы сделать его MEX-функцией. Мы заменим main функцию:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
..
}

и вместо получения аргументов в argc/argv мы получим параметры из входного mxArray. Итак, что-то вроде:

if (nrhs<3 || nlhs>0)
    mexErrMsgIdAndTxt("mex:error", "Wrong number of arguments");

if (!mxIsChar(prhs[0]) || !mxIsChar(prhs[1]) || !mxIsChar(prhs[2]))
    mexErrMsgIdAndTxt("mex:error", "Expects string arguments");

char *filename = mxArrayToString(prhs[0]);
unsigned char * im = readPPM(filename, W, H );
mxFree(filename);

//... same for the other input arguments
// The example receives three arguments: input image, annotation image,
// and output image, all specified as image file names.

// also replace all error message and "return" exit points
// by using "mexErrMsgIdAndTxt" to indicate an error

Наконец, мы скомпилируем модифицированный MEX файл (поместите скомпилированную LIB в ту же папку example):

>> mex -largeArrayDims dense_inference.cpp util.cpp -I. -I../include densecrf.lib

Теперь мы вызываем MEX-функцию изнутри MATLAB:

>> dense_inference im1.ppm anno1.ppm out.ppm

Полученное сегментированное изображение:

Изображение 174551

  • 0
    Я забыл упомянуть, что вам придется комментировать пару строк в src/permutohedral.h если вы работаете в Windows (очевидно, функция round была излишне переопределена в строке 50)
  • 0
    Я попробую это, как только вернусь к своей машине. Большое спасибо. Хотя я использую Linux-машину, но я надеюсь, что большинство шагов будет аналогичным. Если нет, не могли бы вы дать несколько четких шагов, пожалуйста?
Показать ещё 9 комментариев
0

Альтернативный подход может заключаться в компиляции вашего большого C++ кода в общую библиотеку (DLL или.so в зависимости от вашей ОС), а затем загрузку этой библиотеки в Matlab с помощью loadlibrary.
После загрузки библиотеки вы можете вызывать каждую из своих функций API с помощью calllib.


Пример: если вы работаете в среде Linux, и у вас есть код C++ в файле myLib.cpp с файлом заголовка myLib.h, то вы можете использовать g++ для создания общей библиотеки

$ g++ -fPic -c myLib.cpp
$ g++ -shared -o myLib.so myLib.o

Теперь, в Matlab, вы можете загрузить библиотеку (предполагая, что файл.so и.h находятся в вашем пути matlab)

>> loadlibrary( 'myLib', 'myLib.h' );
  • 0
    Могу ли я собрать всю мою библиотеку в один файл .so? Если да, то как? У меня есть это сомнение, потому что я просматривал документацию по общей библиотеке и не понял, как мне это сделать. Ваша помощь высоко ценится.
  • 0
    @diggy ты работаешь в среде Linux или Windows?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню