Вызовите API-функции MATLAB Compiler SDK с C/C++

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

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

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

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

Создайте разделяемую библиотеку, как объяснено в, Создают C/C++ Разделяемые Библиотеки из Командной строки. Если ваша разделяемая библиотека создается, выполните следующий mbuild команда, которая соответствует вашей платформе разработки. Эта команда использует ваш компилятор C/C++, чтобы скомпилировать код и соединиться, код драйвера против MATLAB сгенерировал совместно использованную библиотеку C/C++.

Для приложения 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 генерирует схему с 8 000 точек.

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

Структура программ тот вызов разделяемые библиотеки

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

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

  2. Вызовите mclInitializeApplication, и протестируйте на успех. Эта функция настраивает глобальное состояние MATLAB Runtime и включает конструкцию экземпляров MATLAB Runtime.

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

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

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

  6. Вызовите mclTerminateApplication к бесплатным ресурсам, сопоставленным с глобальным состоянием MATLAB Runtime.

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

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

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

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

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

bool libtriangleInitialize(void)

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

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

bool libtriangleInitializeWithHandlers(
    mclOutputHandlerFcn error_handler,
    mclOutputHandlerFcn print_handler
)

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

Примечание

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

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

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

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

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

void libtriangleTerminate(void)

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

Печать и функции обработки ошибок

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

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

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

static int mclDefaultPrintHandler(const char *s)

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

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

static int mclDefaultErrorHandler(const char *s)

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

Внимание

Обработчик ошибок, несмотря на его имя, не обрабатывает фактические ошибки, а скорее сообщение, произведенное после того, как ошибки были зафиксированы и обработаны в MATLAB Runtime. Вы не можете использовать эту функцию, чтобы изменить поведение обработки ошибок MATLAB Runtime - используют 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 берет тот же тип и количество аргументов как MEX-функция MATLAB. (Дополнительную информацию см. во Внешней документации Интерфейсов относительно 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 функция не является ПУСТОЙ, mlf функция попытается освободить их использующий mxDestroyArray. Это означает, что можно снова использовать выходные переменные в последовательных вызовах mlf функции, не вызывая беспокойство об утечках памяти. Это также подразумевает, что необходимо передать любой NULL или допустимый массив MATLAB для всех выходных переменных или вашей программы перестанет работать, потому что диспетчер памяти не может различать неинициализированный (недопустимый) указатель массивов и допустимый массив. Это попытается освободить указатель, который не является ПУСТЫМ - освобождение недопустимого указателя обычно вызывает отказ сегментации или подобную фатальную ошибку.

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

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

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

Например, рассмотрите этот интерфейс файла 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.  mlx C++ интерфейс для функций MATLAB не изменяется, даже если функции используют varargin или varargout. Однако C++ функционирует интерфейс (второй набор функций) изменения, если функция MATLAB использует varargin или varargout.

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

Примечание

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

 функционируйте varargout = нечто (varargin)

 функционируйте varargout = нечто (i1, i2, varargin)

 функция [o1, o2, varargout] = нечто (varargin)

 функция [o1, o2, varargout] = нечто (i1, i2, varargin)

Получение информации о состоянии MATLAB Runtime, в то время как пользующиеся разделяемые библиотеки

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

Смотрите также

Похожие темы