MATLAB.Exponenta
–Û·Ë͇ Matlab&Toolboxes

MATLAB\MATLAB Compiler

Создание DLL и их использование 

В связи с тем, что этот вопрос многих интересует, а раздел FAQ находится пока в стадии проектирования, я попытаюсь рассказать, как создавать из m-файлов DLL, которые затем можно было бы использовать из C/C++, и, возможно Delphi.

К сожалению, в наличии у меня имеется только стандартный набор разработчика LCC-WIN32 из поставки MATLAB, поэтому все действия я буду описывать с ним. Если кто-то адаптирует это для VC++ будет очень замечательно.

Итак, наша цель...
У нас m-файл, содержащий функцию/функции, которые мы хотели бы сделать доступными для внешних языков.

Буду рассказывать на примере файла additor.m:

    function result = additor(x,y)
    result = x + y;

Для начала, нам нужно откомпилировать m-файл в C. Это делается строкой 'mcc -x additor.m'. Тип wrapper'а (обёртки) указываем EXE потому, что нам всё равно, какую обёртку использовать (мы напишем свою).

После того, как дело сделано, следующий шаг - написание обёртки.

В обёртке, сгенерированной компилятором, имеются следующие строки:

    int main(int argc, const char * * argv)
    {
    return mclMain(argc, argv, mlxAdditor, 1, &_main_info);
    }

Убираем их.

Также в строке 'static _mex_information _main_info' убираем модификатор static для доступа к '_main_info' извне.

Теперь, можно приступить к написанию переходников из C в mex.

Нам понадобится создание DLL-startup процедуры для инициализации библиотек MATLAB. Для этого создаём файл main.c, следующего содержания

    #include
    #include
    #include 'libmatlb.h'
    #include 'additor.h'

    extern _mex_information _mex_info;

    BOOL APIENTRY LibMain(HINSTANCE hInst, DWORD reason, LPVOID reserved)
    {
    int res = 0;

    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    mclLibInitCommon(&_mex_info);
    mclLibhgInit(&res, &_mex_info);
    break; 
    case DLL_PROCESS_DETACH:
    mclLibTermCommon(&_mex_info);
    mclLibhgTerm(&res, &_mex_info);
    break;
    }
    return TRUE;
    }

Теперь, можно написать непосредственно переходник C-MEX.

Это будет функция 'double additor(double x, double y)', которая осуществляет вызов MEX-процедуры. Эту функцию добавим также в main.c

    double additor(double x, double y)
    {
    mxArray* pX = NULL;
    mxArray* pY = NULL;
    mxArray* result = NULL;
    double res;

    mlfAssign(&pX, mlfScalar(x));
    mlfAssign(&pY, mlfScalar(y));
    result = mlfAdditor(pX, pY);
    res = *mxGetPr(result);
    mxDestroyArray(pX);
    mxDestroyArray(pY);
    return res;
    }

Итак, динамическая библиотека почти готова. Осталось лишь скомпилировать её.

Однако, по-умолчанию lcc использует свою LibMain процедуру для динамических библиотек, что не позволит нам автоматически вызвать процедуры инициализации. Чтобы этого избежать, исправим опции компилятора.

В Win2k они хранятся в 'C:\Documents and Settings\seleznev\Application Data\MathWorks\MATLAB\R12\compopts.bat', соответственно путь зависит от системного диска и от имени пользователя.

Там находим строчку 'set DLLLINKFLAGS='.
Необходимо, чтобы она выглядела как
'set DLLLINKFLAGS=-dll '%LIB_NAME%.def' %LINKFLAGS%'.

Теперь, система будет использовать нашу LibMain процедуру и нам не придётся проводить никаких дополнительных шагов по инициализации библиотек.

Создадим файл экспортируемых функций additor.exports, состоящий из 2-х строк:

    LibMain
    additor

Библиотека компилируется следующим образом:

    'mbuild main.c additor.c additor_mex.c additor.exports'

После выполнения этой команды будут созданы файлы main.dll и main.lib

Как использовать полученную библиотеку?

Напишем простенькую программу test.c (теоретически, можно и на Delphi).

    #include <stdio.h>
    double additor(double x, double y);
    void main()
    {
    printf('10+20=%f', additor(10,20););
    }

Скомпонуем теперь её с библиотекой main.lib
Проще всего, это сделать 'mbuild test.c main.lib'.

Получится программа test.exe.
Дистрибутив нашего 'приложения' будут составлять файлы test.exe, main.dll и... весь runtime MATLAB'а, входящий в 'mglinstaller.exe'.

Приведённую выше последовательность действий не стоит понимать буквально (однако, всё что написано выше было проделано на практике). Она лишь иллюстрирует идеи, которые позволяют добиться цели - создания stand-alone библиотеки, пригодной для использования из различных языков программирования.

Заранее спасибо всем, кто откликнется и выскажет ценные замечания.

С уважением, Алексей Селезнёв.


Поиск по сайту:

Система Orphus

Яндекс.Метрика