Общая библиотека, сгенерированная MATLAB® Compiler SDK™ содержит по меньшей мере семь функций. Существует три сгенерированные функции для управления инициализацией и завершением библиотеки, по одной для распечатанных выходов и сообщений об ошибке и две сгенерированные функции для каждого файла MATLAB, скомпилированного в библиотеку.
Чтобы сгенерировать функции, описанные в этом разделе, сначала скопируйте sierpinski.m
и triangle.c
чтобы создать общую библиотеку на C, triangle_legacy.cpp
для создания mwArray
C++ Общая библиотека API, или
triangle_generic.cpp
чтобы создать общую библиотеку MATLAB Data API C++ в вашей директории. Файлы найдены в
.matlabroot
\ extern\примеры\compilersdk\c _ cpp\треугольник
Создайте общую библиотеку, как описано в разделе «Создание общих библиотек C/C + + из командной строки». После создания общей библиотеки выполните следующее mbuild
команда, которая соответствует вашей платформе разработки. Эта команда использует ваш компилятор C/C + +, чтобы скомпилировать код и связать код драйвера с общей библиотекой на C/C + +, сгенерированной MATLAB.
Для приложения на C используйте mbuild triangle.c libmatrix.lib
.
Для mwArray C++
Приложение API, используйте mbuild triangle_legacy.cpp libtriangle.lib
Для приложения C++ MATLAB Data API используйте mbuild matrix_mda.cpp libtriangle.lib
Примечание
The .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, сгенерировали общие библиотеки, имеют примерно одинаковую структуру:
Объявить переменные и обработать/проверить входные параметры.
Функции mclInitializeApplication
, и тест на успех. Эта функция устанавливает глобальное состояние MATLAB Runtime и включает конструкцию образцов MATLAB Runtime.
Позвоните, один раз для каждой библиотеки, <libraryname>Initialize
, чтобы создать образец MATLAB Runtime, требуемый библиотекой.
Активируйте функции в библиотеке и обрабатывайте результаты. (Это основная часть программы.)
Позвоните, один раз для каждой библиотеки, <libraryname>Terminate
, чтобы уничтожить связанную среду MATLAB Runtime.
Функции mclTerminateApplication
чтобы освободить ресурсы, сопоставленные с глобальным состоянием MATLAB Runtime.
Очистка переменных, закрытие файлов и т.д. и выход.
Чтобы увидеть эти шаги в фактическом примере, рассмотрим основную программу в этом примере, triangle.c
.
Функции инициализации и завершения работы библиотеки создают и уничтожают, соответственно, образец MATLAB Runtime, требуемый общей библиотекой. Вы должны вызвать функцию инициализации, прежде чем вы активируете любую из других функций в общей библиотеке, и вы должны вызвать функцию завершения после завершения вызовов в общей библиотеке (или вы рискуете утечкой памяти).
Существует две формы функции инициализации и один тип функции завершения. Более простая из двух функций инициализации не принимает аргументов; скорее всего, это версия, которую вызовет ваше приложение. В этом примере эта форма функции инициализации вызывается libtriangleInitialize
.
bool libtriangleInitialize(void)
Эта функция создает образец MATLAB Runtime с помощью обработчиков печати и ошибок по умолчанию, а также другой информации, сгенерированной в процессе компиляции.
Однако, если вы хотите больше контролировать, как обрабатываются распечатанные выходы и сообщения об ошибке, можно вызвать вторую форму функции, которая принимает два аргумента.
bool libtriangleInitializeWithHandlers( mclOutputHandlerFcn error_handler, mclOutputHandlerFcn print_handler )
При вызове этой функции можно предоставить собственные версии стандартных программ печати и обработки ошибок, вызываемых MATLAB Runtime. Каждая из этих стандартных программ имеет одну и ту же сигнатуру (подробные сведения см. в разделах Функции печати и обработки ошибок). Переопределяя значения по умолчанию, можно управлять отображением вывода и, например, переходом его в файл журнала.
Примечание
Перед вызовом любой формы стандартной программы инициализации библиотеки необходимо сначала вызвать mclInitializeApplication
для настройки глобального состояния MATLAB Runtime. Дополнительные сведения см. в разделе Вызов разделяемой библиотеки на С.
На 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 Compiler SDK, продукт генерирует две функции, mlx
функции и mlf
функция. Каждая из этих сгенерированных функций выполняет одно и то же действие (вызывает функцию файла MATLAB). Эти две функции имеют различные имена и представляют различные интерфейсы. Имя каждой функции основано на имени первой функции в файле MATLAB (sierpinski
, в этом примере); каждая функция начинается с другого трехбуквенного префикса.
Примечание
Для разделяемых библиотек C MATLAB Compiler SDK генерирует mlx
и mlf
функции, как описано в этом разделе. Для разделяемых библиотек C++ продукт генерирует mlx
функционировать так же, как для общей библиотеки C. Однако продукт генерирует измененную mlf
функция с этими различиями:
The mlf
прежде чем имя функции будет сброшено, чтобы сохранить совместимость с R13.
Аргументы к функции mwArray
вместо mxArray
.
Функция, которая начинается с префикса mlx
принимает тот же тип и количество аргументов, что и MATLAB MEX-функция. (Для получения дополнительной информации о функциях MEX см. документацию по внешним интерфейсам.) Первый аргумент, nlhs
, количество выходных аргументов и второй аргумент, plhs
, - указатель на массив, который функция заполнит требуемым количеством возврата значений. (The "lhs
"в этих именах аргумента кратки для" left-hand "- выходные переменные в выражении MATLAB указаны в левой части оператора назначения.) Третий и четвертый параметры являются количеством входов и массивом, содержащим входные переменные.
void mlxSierpinski(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
Вторая из сгенерированных функций начинается с префикса 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 - освобождение недопустимого указателя обычно приводит к ошибке сегментации или подобной фатальной ошибке.
Если ваша Функция MATLAB интерфейс использует varargin
или varargout
Вы должны передать их как массивы ячеек. Для примера, если у вас есть N
varargin
s, вам нужно создать один массив ячеек размера 1-by-N
. Точно так же varargout
s возвращаются назад как один массив ячеек. Длина varargout
равно количеству значений возврата, заданному в вызове функции минус количество переданных фактических переменных. Как и в программном обеспечении MATLAB, массив ячеек, представляющий varagout
должна быть последней возвращаемой переменной (переменная, предшествующая первой входной переменной) и массивом ячеек, представляющим varargin
s должен быть последним формальным параметром вызова функции.
Для получения информации о создании массивов ячеек см. функциональный интерфейс 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 Использование вараргина и вараргаута. Система C++ mlx
интерфейс для функций MATLAB не меняется, даже если функции используют varargin
или varargout
. Однако интерфейс функции C++ (второй набор функций) изменяется, если функция MATLAB использует varargin
или varargout
.
Для примеров просмотрите сгенерированный код для различных сигнатур функции MATLAB, которые используют varargin
или varargout
.
Примечание
Для простоты в следующих примерах показана только соответствующая часть сгенерированной сигнатуры функции C++.
function varargout = foo (varargin)
function varargout = foo (i1, i2, varargin)
При использовании общих библиотек можно вызвать функцию для извлечения конкретной информации из состояния MATLAB Runtime. Для получения дополнительной информации см. раздел «Установка и извлечение данных MATLAB Runtime для общих библиотек».