exponenta event banner

Вызов функций API SDK компилятора MATLAB из C/C + +

Функции в общей библиотеке

Общая библиотека, созданная компилятором MATLAB ® SDK™, содержит не менее семи функций. Существует три сгенерированные функции для управления инициализацией и завершением библиотеки, по одной для распечатанных выходных сообщений и сообщений об ошибках, и две сгенерированные функции для каждого файла MATLAB, скомпилированного в библиотеку.

Для создания функций, описанных в этом разделе, сначала скопируйте sierpinski.m и triangle.c для создания общей библиотеки C, triangle_legacy.cpp для создания C++ mwArray Общая библиотека API или triangle_generic.cpp для создания общей библиотеки C++ MATLAB Data API в каталоге. Файлы найдены в matlabroot\extern\examples\compilersdk\c_cpp\triangle.

Тип приложения

Создайте общую библиотеку, как описано в разделе «Создание общих библиотек C/C + + из командной строки». После создания общей библиотеки выполните следующие действия.mbuild команду, соответствующую вашей платформе разработки. Эта команда использует компилятор C/C + + для компиляции кода и связывания кода драйвера с общей библиотекой C/C + +, созданной MATLAB.

Для приложения C используйте mbuild triangle.c libmatrix.lib.

Для C++ mwArray Приложение API, использование mbuild triangle_legacy.cpp libtriangle.lib

Для приложения C++ MATLAB Data API используйте mbuild matrix_mda.cpp libtriangle.lib

Примечание

.lib для Windows ®. На Mac расширение файла: .dylib, и в UNIX ® это .so.

Эта команда предполагает, что общая библиотека C/C + +, код драйвера и соответствующий файл заголовка находятся в текущей рабочей папке.

Эти команды создают основную программу с именем triangleи общая библиотека с именем libtriangle. Библиотека экспортирует одну функцию, использующую простой итеративный алгоритм (содержится в sierpinski.m) для генерации фрактала, известного как Треугольник Серпинского. Основная программа в triangle.c, triangle_legacy.cpp, и triangle_generic.cpp может опционально принимать одиночный числовой аргумент, который при наличии указывает количество точек, используемых для генерации фрактала. Например, triangle 8000 генерирует диаграмму с 8000 точками.

В этом примере MATLAB Compiler SDK помещает все созданные функции в созданный файл libtriangle.c или libtriangle.cpp.

Структура программ, вызывающих общие библиотеки

Все программы, которые вызывают MATLAB Compiler SDK, создаваемые общими библиотеками, имеют примерно одинаковую структуру:

  1. Объявить переменные и обработать/проверить входные аргументы.

  2. Звонить mclInitializeApplicationи проверить на успех. Эта функция устанавливает глобальное состояние среды выполнения MATLAB и позволяет создавать экземпляры среды выполнения MATLAB.

  3. Вызов, один раз для каждой библиотеки, <libraryname>Initialize, для создания экземпляра среды выполнения MATLAB, необходимого библиотеке.

  4. Вызов функций в библиотеке и обработка результатов. (Это основная часть программы.)

  5. Вызов, один раз для каждой библиотеки, <libraryname>Terminate, чтобы уничтожить связанную среду выполнения MATLAB.

  6. Звонить mclTerminateApplication для освобождения ресурсов, связанных с глобальным состоянием среды выполнения MATLAB.

  7. Очистка переменных, закрытие файлов и т.д., выход.

Чтобы увидеть эти шаги в фактическом примере, просмотрите основную программу в этом примере, triangle.c.

Функции инициализации и завершения библиотеки

Функции инициализации и завершения библиотеки создают и уничтожают, соответственно, экземпляр среды выполнения MATLAB, необходимый для общей библиотеки. Перед вызовом любой из других функций в общей библиотеке необходимо вызвать функцию инициализации, а после завершения выполнения вызовов в общую библиотеку (или возникновения угрозы утечки памяти) следует вызвать функцию завершения.

Существует две формы функции инициализации и один тип функции завершения. Более простое из двух функций инициализации не принимает аргументов; скорее всего, это та версия, которую вызовет ваше приложение. В этом примере эта форма функции инициализации называется libtriangleInitialize.

bool libtriangleInitialize(void)

Эта функция создает экземпляр среды выполнения MATLAB с использованием обработчиков печати и ошибок по умолчанию, а также другой информации, созданной в процессе компиляции.

Однако если требуется больше контроля над тем, как обрабатываются печатные выходные сообщения и сообщения об ошибках, можно вызвать вторую форму функции, которая принимает два аргумента.

bool libtriangleInitializeWithHandlers(
    mclOutputHandlerFcn error_handler,
    mclOutputHandlerFcn print_handler
)

Вызов этой функции позволяет создать собственные версии процедур печати и обработки ошибок, вызываемых средой выполнения MATLAB. Каждая из этих подпрограмм имеет одинаковую сигнатуру (подробные сведения см. в разделе Функции печати и обработки ошибок). Переопределяя значения по умолчанию, можно управлять отображением выходных данных и, например, переносом их в файл журнала.

Примечание

Перед вызовом любой из форм процедуры инициализации библиотеки необходимо сначала вызвать mclInitializeApplication для настройки глобального состояния среды выполнения MATLAB. Дополнительные сведения см. в разделе Вызов общей библиотеки C.

На платформах Microsoft ® Windows MATLAB Compiler SDK генерирует дополнительную функцию инициализации, стандартную функцию инициализации Microsoft DLLDllMain.

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason,  
                    void *pv)

Произведенный DllMain выполняет очень важную услугу; он определяет каталог, в котором хранится общая библиотека на диске. Эта информация используется для поиска развертываемого архива, без которого приложение не будет выполняться. При изменении созданного DllMain (не рекомендуется), убедитесь, что эта часть функциональности сохранена.

Завершение работы библиотеки просто.

void libtriangleTerminate(void)

Вызовите эту функцию (один раз для каждой библиотеки) перед вызовом mclTerminateApplication.

Функции печати и обработки ошибок

По умолчанию MATLAB Compiler SDK создает приложения и общие библиотеки, отправляя распечатанные выходные данные на стандартный вывод, а сообщения об ошибках - на стандартный. MATLAB Compiler SDK создает обработчик печати по умолчанию и обработчик ошибок по умолчанию, реализующие эту политику. Чтобы изменить это поведение, необходимо записать собственные обработчики ошибок и печати и передать их в соответствующую созданную функцию инициализации.

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

Обработчик печати по умолчанию принимает следующую форму.

static int mclDefaultPrintHandler(const char *s)

Осуществление является простым; он принимает строку, печатает ее на стандартном выходе и возвращает количество напечатанных символов. При переопределении или замене этой функции версия должна также принимать строку и возвращать количество символов «обработано». Среда выполнения MATLAB вызывает обработчик печати, когда исполняемый файл MATLAB делает запрос на вывод на печать, например, через функцию MATLAB. disp. Обработчик печати не завершает вывод возвратом каретки или подачей строки.

Обработчик ошибок по умолчанию имеет ту же форму, что и обработчик печати.

static int mclDefaultErrorHandler(const char *s)

Однако реализация обработчика печати по умолчанию несколько отличается. Он отправляет выходные данные в стандартный выходной поток ошибок, но если строка не заканчивается возвратом каретки, обработчик ошибок добавляет один. Если обработчик ошибок по умолчанию заменен на собственный обработчик, следует также выполнить эту проверку, или некоторые сообщения об ошибках, напечатанные во время выполнения MATLAB, не будут правильно отформатированы.

Внимание

Обработчик ошибок, несмотря на свое имя, обрабатывает не фактические ошибки, а сообщение, созданное после обнаружения и обработки ошибок в среде выполнения MATLAB. Вы не можете использовать эту функцию для изменения поведения обработки ошибок во время выполнения MATLAB - используйте try и catch операторы в файлах MATLAB, если вы хотите управлять тем, как создаваемое приложением MATLAB Compiler SDK реагирует на состояние ошибки.

Примечание

При наличии альтернативных реализаций C++ mclDefaultPrintHandler или mclDefaultErrorHandler, то функции должны быть объявлены extern "C". Например:

extern "C" int myPrintHandler(const char *s); 

Функции, созданные из файлов MATLAB

Для каждого файла MATLAB, указанного в командной строке MATLAB Compiler SDK, продукт генерирует две функции: mlx функции и mlf функция. Каждая из этих сгенерированных функций выполняет одно и то же действие (вызывает функцию файла MATLAB). Эти две функции имеют разные имена и представляют различные интерфейсы. Имя каждой функции основано на имени первой функции в файле MATLAB (sierpinski, в этом примере); каждая функция начинается с различного трехбуквенного префикса.

Примечание

Для общих библиотек C MATLAB Compiler SDK генерирует mlx и mlf функции, описанные в этом разделе. Для общих библиотек C++ продукт генерирует mlx функционирует так же, как и для общей библиотеки C. Однако продукт генерирует модифицированный mlf функция с этими различиями:

  • mlf перед удалением имени функции для обеспечения совместимости с R13.

  • Аргументы функции: mwArray вместо mxArray.

Функция интерфейса mlx

Функция, начинающаяся с префикса mlx принимает тот же тип и количество аргументов, что и MATLAB MEX-функция. (Для получения дополнительной информации о функциях MEX см. документацию по внешним интерфейсам.) Первый аргумент, nlhs, - количество выходных аргументов и второй аргумент, plhs, является указателем на массив, который функция заполнит требуемым количеством возвращаемых значений. ("lhs"в этих именах аргументов сокращение от" левая сторона "- выходные переменные в выражении MATLAB находятся в левой части оператора назначения.) Третий и четвертый параметры - это количество входов и массив, содержащий входные переменные.

void mlxSierpinski(int nlhs, mxArray *plhs[], int nrhs,
                   mxArray *prhs[])

Функция интерфейса MLF

Вторая из созданных функций начинается с префикса mlf. Эта функция ожидает, что ее входные и выходные аргументы будут переданы в виде отдельных переменных, а не упакованы в массивы. Если функция способна создавать один или несколько выходов, первым аргументом является количество выходов, запрошенных вызывающим абонентом.

void mlfSierpinski(int nargout, mxArray** x, mxArray** y,
                   mxArray* iterations, mxArray* draw)

В обоих случаях созданные функции распределяют память для возвращаемых значений. Если не удалить эту память (через mxDestroyArray) когда вы закончите с выходными переменными, ваша программа утечет память.

Программа может вызывать любую из этих функций более удобной, так как обе они вызывают функцию файла MATLAB идентичным образом. Большинство программ, скорее всего, назовут mlf форма функции, чтобы избежать управления дополнительными массивами, требуемыми mlx форма. Пример программы в triangle.c требования mlfSierpinski.

mlfSierpinski(2, &x, &y, iterations, draw);

В этом вызове вызывающий абонент запрашивает два выходных аргумента: x и yи обеспечивает два входа, iterations и draw.

Если выходные переменные передаются в mlf функции не равны NULL, mlf функция попытается освободить их с помощью mxDestroyArray. Это означает, что можно повторно использовать выходные переменные при последовательных вызовах mlf функционирует без беспокойства по поводу утечек памяти. Это также подразумевает, что вы должны пройти либо NULL или допустимый массив MATLAB для всех выходных переменных, или программа завершится ошибкой, так как диспетчер памяти не может различить неинициализированный (недопустимый) указатель массива и допустимый массив. Он попытается освободить указатель, который не имеет значения NULL - освобождение неверного указателя обычно приводит к сбою сегментации или аналогичной неустранимой ошибке.

Использование varargin и varargout в функциональном интерфейсе MATLAB

Если используется интерфейс функции MATLAB varargin или varargout, вы должны передать их как массивы ячеек. Например, если имеется N varargins, необходимо создать один массив ячеек размера 1-by-N. Аналогично, varargouts возвращаются как один массив ячеек. Длина varargout равно количеству возвращаемых значений, указанных в вызове функции, минус количество переданных фактических переменных. Как и в программном обеспечении MATLAB, массив ячеек представляет varagout должна быть последней возвращаемой переменной (переменная, предшествующая первой входной переменной) и массивом ячеек, представляющим varargins должен быть последним формальным параметром вызова функции.

Для получения информации о создании массивов ячеек см. функциональный интерфейс C MEX в документации по внешним интерфейсам.

Например, рассмотрим следующий интерфейс файла MATLAB:

[a,b,varargout] = myfun(x,y,z,varargin)

Соответствующий интерфейс C для этого:

void mlfMyfun(int numOfRetVars, mxArray **a, mxArray **b, 
              mxArray **varargout, mxArray *x, mxArray *y,
              mxArray *z, mxArray *varargin)

В этом примере количество элементов в varargout является (numOfRetVars - 2), где 2 представляет две переменные, a и b, будучи возвращенным. Оба varargin и varargout представляют собой однострочные массивы с несколькими ячейками столбцов.

Внимание

Интерфейс общей библиотеки C++ не поддерживает varargin с нулем (0) входных аргументов. Вызов программы с помощью пустой mwArray приводит к получению пакетной библиотекой пустого массива с nargin = 1. Интерфейс общей библиотеки C позволяет выполнять вызовы mlfFOO(NULL) (упакованный код MATLAB интерпретирует это как nargin=0). Тем не менее, вызов FOO((mwArray)NULL) с помощью интерфейса общей библиотеки C++ упакованный код MATLAB видит пустой массив в качестве первого ввода и интерпретирует nargin=1.

Например, пакетировать некоторый код MATLAB как общую библиотеку C++ с помощью varargin в качестве списка входных аргументов функции MATLAB. Отображение переменной в коде MATLAB nargin. Вызов библиотеки с функцией FOO() и он не будет упаковываться, создавая следующее сообщение об ошибке:

... 'FOO' : function does not take 0 arguments
Вызовите библиотеку следующим образом:
  mwArray junk; 
  FOO(junk); 
или
 FOO((mwArray)NULL);
Во время выполнения, nargin=1. В MATLAB, FOO() является nargin=0 и FOO([]) является nargin=1.

Интерфейсы C++ для функций MATLAB с использованием varargin и varargout.  C++ mlx интерфейс для функций MATLAB не изменяется, даже если используются функции varargin или varargout. Однако интерфейс функции C++ (второй набор функций) изменяется, если используется функция MATLAB. varargin или varargout.

Например, просмотрите созданный код для различных сигнатур функций MATLAB, которые используют varargin или varargout.

Примечание

Для простоты в следующих примерах показана только соответствующая часть сгенерированной сигнатуры функции C++.

 функция varargout = foo (varargin)

 функция varargout = foo (i1, i2, varargin)

 функция [o1, o2, varargout] = foo (varargin)

 функция [o1, o2, varargout] = foo (i1, i2, varargin)

Получение сведений о состоянии среды выполнения MATLAB при использовании общих библиотек

При использовании общих библиотек можно вызывать функции для получения определенной информации из состояния MATLAB Runtime. Дополнительные сведения см. в разделе Установка и извлечение данных среды выполнения MATLAB для общих библиотек.

См. также

Связанные темы