Как файлы MATLAB mex получают доступ к экземплярам MATLAB?

Это точка входа для каждого файла mex:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);

На самом деле файлы mex - это файлы DLL Windows с функцией mexFunction в качестве основной функции. Мой вопрос: когда вызывается функция mex, как она может получить доступ к данным экземпляра Matlab изнутри mex. В качестве примера рассмотрим функцию mexPutVariable. Его задача - «скопировать массив изнутри MEX-функции в указанную рабочую область (вне mex)». Но откуда ему знать, где «рабочее место». В mex не был передан параметр (например, указатель), содержащий данные экземпляра Matlab (вызывающий объект). Файлы mex знают только nlhs, plhs, nrhs, prhs, и ни один из них не может помочь файлам mex извлекать данные, специфичные для экземпляра Matlab (информация о функциях вызывающего абонента).


person Mehrdad Nazmdar    schedule 30.12.2015    source источник


Ответы (1)


Возможное решение состоит в том, что "Matlab.exe" объявляет mexPutVariable как экспортируемую функцию:

[Matlab.exe]

int __declspec(dllexport) mexPutVariable(const char* workspace, const char* name, const mxArray* parray)
{
    ...
}

Тогда очень легко получить эту функцию из dll, используя _ 4_ и _ 5_:

[Module.dll]

// Declare function pointer 
int (*FctnPtr)(const char* workspace, const char* name, const mxArray* parray);

// Retreive the main executable 
HANDLE hExe = GetModuleHandle(NULL);

// Link to exported function in the exe just like you would do for any dll    
FctnPtr mexPutVariable = (FctnPtr)GetProcAddress(hExe, "mexPutVariable");

// Use exported function from the dll
mexPutVariable("Base", "foo", myArray);

Для компиляции файла mex и после просмотра файла mex.h mexPutVariable объявляется как внешняя функция для связи с:

LIBMWMEX_API_EXTERN_C int mexPutVariable(const char* workspace, const char* name, const mxArray* parray);

Что оказывается просто (при компиляции как сторона dll):

 extern "C" int mexPutVariable(const char* workspace, const char* name, const mxArray* parray);
person CitizenInsane    schedule 30.12.2015
comment
Это возможный ответ или реальный ответ? - person Mehrdad Nazmdar; 30.12.2015
comment
У меня нет источника Matlab, поэтому это может быть только предположение ... в любом случае, не передавая указатели на dll, я не вижу другого разумного решения для обратного вызова в основной процесс. - person CitizenInsane; 30.12.2015
comment
В качестве альтернативы, возможно, в .lib ваш исходный файл mex связан с экспортированной функцией, которую также вызывает Matlab, чтобы инициализировать mexPutVariable и т.д. (т.е. передать простой указатель во время инициализации). - person CitizenInsane; 30.12.2015
comment
Думаю, это не изменило бы ситуацию. Ты прав. Я думаю, что единственно возможный ответ - это то, что вы упомянули в своем ответе. внутри .lib есть ссылки на другие dll. Я думаю, что в этих dll реализована упомянутая вами стратегия. - person Mehrdad Nazmdar; 30.12.2015
comment
Но если бы я мог решить, как это сделать, я бы добавил параметр с именем handle для передачи данных конкретного экземпляра MATLAB. например: void mexFunction (int handle, int nlhs, mxArray * plhs [], int nrhs, const mxArray * prhs []); затем добавьте дескриптор к каждой функции, которая использует рабочее пространство MATLAB, например: mexPutVariable (int handle, ...); [дескриптор - это адрес структуры данных экземпляра Matlab] - person Mehrdad Nazmdar; 30.12.2015
comment
Более волшебно расширять Matlab, не показывая / не беспокоясь о клее;) - person CitizenInsane; 30.12.2015
comment
Это один из недостатков использования программного обеспечения с закрытым исходным кодом. - person Mehrdad Nazmdar; 30.12.2015