![]()
Главная Обратная связь Дисциплины:
Архитектура (936) ![]()
|
Тема 11. Написание расширений MATLAB на языке C
Существует несколько способов взаимодействия системы MATLAB с внешними программами: · Во-первых, можно написать расширение MATLAB на обычных языках программирования, таких как С/С++, Fortran и т.п. · Наоборот, можно вызвать вычислительное ядро MATLAB из своей программы и получить результат вычислений среды MATLAB в свою программу. В этом случае MATLAB выступает как своего рода вычислительный сервер для внешней программы. · Средой MATLAB можно управлять при помощи команд DDE (Dynamic Data Exchange) или ActiveX (OLE) Automation. · Наконец, можно просто обмениваться данными со средой MATLAB через MAT-файлы, структура которых описана в документации к системе. Нетрудно видеть, что предоставляемый набор способов взаимодействия с системой внешних программ является весьма полным и гибким. Практически все эти способы описаны в документации к системе, однако, так как наиболее часто используется первый способ, сосредоточимся на нем. Обычно, пользователь-программист работает с системой MATLAB непосредственно, кодируя необходимые алгоритмы на встроенном языке MATLAB. Встроенный язык весьма удобен для написания математических алгоритмов – писать и отлаживать на нем программу обычно занимает значительно меньше времени, чем на обычных языках программирования. Однако, довольно часто эффективность подобных программ оставляет желать лучшего. Как правило, подобная ситуация возникает, когда алгоритм плохо векторизуется, например, при обработке матриц нельзя выразить этот алгоритм, пользуясь векторными операторами языка MATLAB, и приходится писать вложенные циклы, перераспределять память и т.п. В этом случае программа на языке С будет исполняться во много раз быстрее аналогичной программы на языке MATLAB. А ведь довольно часто время счета математической задачи может исчисляться сутками. Кроме того, иногда возникают ситуации, когда те или иные сложные алгоритмы уже были реализованы на других языках программирования. В этом случае также будет быстрее не переписывать весь алгоритм на языке MATLAB, но написать относительно небольшой «переходник» от MATLAB к уде существующему на языке С модулю и вызвать его из среды MATLAB напрямую. Для того, чтобы написать модуль, расширяющий набор функций MATLAB, нужно создать обычную динамическую библиотеку (DLL) для Microsoft Windows со специальным набором функций (интерфейсом). Данная библиотека может быть создана при помощи многих компиляторов языка С/С++, однако, наиболее часто используется компилятор разработки компании Microsoft – Visual C++, одной из последних версий которого (5.0) мы и воспользуемся для подготовки наших примеров. В документации по системе MATLAB для подобных расширений употребляется термин MEX-файл (Matlab EXtension), и сама MATLAB по этому расширению имени файла может определить, что данный модуль является ее расширением. Хотя, специально назначать MEX в качестве расширения имени файла необязательно, MATLAB может прекрасно работать и со стандартным расширением подобных динамических библиотек – DLL. Папка \matlab\extern на диске, на котором установлена система, содержит все необходимые файлы-заголовки для программ на С (каталог \matlab\extern\include), а также несколько примеров модулей (\matlab\extern\examples), реализующих некоторые расширения системы, которые приведены целиком в виде исходных текстов программ на С. Кроме того, имеется папка \matlab\extern\src в которой приведен исходный текст некоторых вспомогательных функций, весьма облегчающий отладку модулей расширения MATLAB. Программные интерфейсы В модулях-расширениях MATLAB (MEX-файлах) для обмена параметрами всех типов с вычислительной средой MATLAB используется ровно одна структура, хотя и чрезвычайно гибкая. Называется эта структура – mxArray (Matlab Extension Array). Все типы данных MATLAB – массивы, скаляры, строки, клеточные и многомерные массивы, объекты и т.п. выражаются при помощи этой единственной структуры. Программный интерфейс создаваемой динамической библиотеки тоже достаточно прост. Должна быть обязательно экспортирована единственная функция с двумя параметрами – входным массивом структур mxArray и выходным массивом структур mxArray. Соответственно, задача модуля расширения заключается в том, чтобы на основе входной информации создать выходной массив. Прототип интерфейсной функции объявлен в заголовочном файле \matlab\extern\include\mex.h следующим образом:
void mexFunction( int nlhs, /* количество выходных параметров */ mxArray *plhs[],/*массив указателей на вых.параметры*/ int nrhs, /* количество входных параметров */ /**/ const mxArray *prhs[]/*массив указ-ей на вход.пар-ры */ ); Отметим, что в английской компьютерной литературе входные и выходные параметры называются “left hand side parameters” (параметры слева от знака присваивания) и “right hand side parameters” (параметры справа от знака присваивания). Сокращения этих названий вошли в имена параметров интерфейсной функции. Рассмотрим структуру mxArray. Помимо прочих, она содержит следующие поля: · имя переменной среды MATLAB в текстовом виде, · размерность данной переменной, · ее тип, · является ли она вещественной или комплексной (в случае комплексной переменной создаются отдельно вектора вещественной и мнимой частей), · является ли переменная разреженной матрицей, так как разреженные матрицы имеют отличную от обычных схему хранения данных. Матрицы (двумерные массивы) являются подмножеством mxArray, для чего в этой структуре предусмотрены поля pr (вещественная часть) и pi (мнимая часть). Каждое из этих полей представляет собой одномерный массив, содержащий элементы матриц (double-числа) поколоночно – сначала все элементы первого столбца матрицы, затем – второго и т.д. Так как извлечение требуемого типа данных для обработки напрямую из общей структуры может быть сложным (из-за наличия разного рода флажков, типов, размерностей и т.п.), то MATLAB содержит специальную библиотеку вспомогательных функций, облегчающую работу с тем или иным типом данных внутри расширения MATLAB. Все функции этой библиотеки, работающие с массивом mxArray, имеют префикс mx (напр. mxGetPr()). Другой набор функций в этой же библиотеке имеет префикс mex (напр. mexPrintf()). В отличие от предыдущих, они осуществляют ту или иную операцию в самой среде MATLAB, например – печатают строку текста. Никакая из этих функций не осуществляет прямого доступа к полям mxArray. Оба указанных набора функций содержатся в динамических библиотеках, находящихся в каталоге \matlab\bin. Эти библиотеки следует подключить к проекту. Не забывайте также включать заголовочный файл mex.h во все исходные файлы вашей программы, в которых используются вызовы функций библиотеки MATLAB или ее типы данных. В заключение, еще раз подчеркнем, что mxArray в состоянии описать любую переменную MATLAB, что и дает возможность написать расширение, работающее с любым типом данных.
![]() |