Передача обратных вызовов C / C ++ в движок matlab - PullRequest
3 голосов
/ 30 января 2012

У меня есть файл C ++, который:

  • запускает механизм Matlab
  • вызывает matlab_optimize() (скомпилированный m-файл, который запускает один из оптимизаторов Matlab внутри)
  • печатает результат
  • останавливает двигатель и завершает работу

Это отлично работает.Теперь я хочу изменить вторую строку на

  • вызывает matlab_optimize(obj_fun)

Где obj_fun() - это функция, определенная в моем коде C ++, которая сама будет вызывать обратный вызов в другой код,По сути, я хочу, чтобы оптимизатор matlab, используемый внутри matlab_optimize, использовал указатель поставляемой функции в качестве целевой функции.

Я не могу просто скомпилировать obj_fun() как отдельный mex-файл, так как я хочу, чтобы он связывался с c ++процесс, который запускает механизм Matlab (который управляет всем этим).

Сообщение в группе новостей от 2009 , похоже, указывает на то, что это невозможно.С другой стороны, Matlab C ++ Math Library Toolbox , похоже, действительно может сделать это .

Поиск в Google также показывает этот сгенерированный фрагмент :

/*
 * Register a function pointer as a MATLAB-callable function.
 */
extern void mexRegisterFunction(void);

Который кажется именно тем, что я хочу, но это файл 2000 года, и я нигде не нахожу ссылки на эту функцию в документах matlab.Так как это использовать?

Ответы [ 5 ]

5 голосов
/ 07 декабря 2012

Вы можете использовать функцию mclCreateSimpleFunctionHandle из заголовка mclmcrrt.h, чтобы сделать эту функцию.

Преобразует функцию с прототипом void (*) (int, mxArray *, int, mxArray) в структуру mxArray.

Вы можете передать его функции стороны MATLAB и вызывать ее как обычные функции MATLAB без каких-либо манипуляций с mex-файлами.

На стороне C / C ++:

void callback(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
   <some manipulations with data>;
}

...
//calling the matlab function
matlab_function(mclCreateSimpleFunctionHandle(callback));

На стороне MATLAB:

function [] = matlab_function(function)
    function(<any variable>)
end
2 голосов
/ 24 февраля 2016

Я хотел бы поблагодарить Тоторо за его полезный комментарий, вот несколько более подробных примеров реализации на стороне C ++:

void fromMatlabCallback(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
  cout << "WOW I'm from Matlab. and it passes me a param: ";
  int aa = mxGetScalar(prhs[0]); // it is first param; nrhs tells how many there are
  cout << aa << "\n";
}

void InitializingFunc()
{
  mxArray *func_ptr = mclCreateSimpleFunctionHandle(fromMatlabCallback);
  mxArray *retVal_ptr = NULL;
  mlfUntitled(1, &retVal_ptr , func_ptr); //Untitled is name of my main Matlab func
}
2 голосов
/ 06 февраля 2012

Я связался с Mathworks по поводу проблемы и сумел заставить все это работать.Этот вопрос был частью более широких усилий по возможности передавать обратные вызовы в функции Python непосредственно в Matlab.

Полная информация о этом сообщении в блоге и код доступен на github .

0 голосов
/ 31 января 2012

Кажется, что вы можете создать c-linkable библиотеку из любой функции MATLAB (см. Здесь) .Если это работает так, как рекламируется, я думаю, что вы сможете делать то, что хотите, хотя и по-другому.

0 голосов
/ 30 января 2012

Если есть способ сделать это, я никогда его не видел. Что еще хуже, математическая библиотека Matlab C ++, на которую вы ссылаетесь, больше не существует:

http://www.mathworks.com/matlabcentral/newsreader/view_thread/267802

...