Copyright © Красноярский государственный университет 2003
Как вызвать функции, написанные на C/C++, из матлаба ЗадачиКак вызвать функции, написанные на C/C++, из матлаба
При инсталляции Matlab необходимо установить Matlab C/C++ math. library. Затем нужно выполнить настройку скриптов матлаба с помощью команды mex -setup, которую можно вводить либо с консоли Matlab, либо с консоли Windows. Эту команду необходимо выполнять пользователю с правами администратора системы, поскольку при этом производятся записи в системные файлы. После этого можно приступать к написанию программы на языках C/C++ или Fortran, которую можно будет вызывать непосредственно из матлаба. В данной лекции рассматривается лишь связь программ на C/C++ с матлабом. Предположим, что необходимо написать программу на языке C вызов которой в командной строке matlab имеет вид [a b]=fun(d,e,f);. Функция fun должна получать три матрицы из матлаба и возвращать после работы две матрицы. Для решения поставленной задачи необходимо написать программу на C с любым количеством функций, но среди них обязательно должна быть функция с именем mexFunction. Эта функция играет такую же роль для наших целей, как функция main для консольных приложений. Функция mexFunction имеет всегда четыре аргумента. void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);. При написании программ на языках C/C++ всегда необходимо включать заголовочный файл mex.h, который хранится в %MATLAB%\extern\include. В файле matrix.h, подключаемом из mex.h, определен типданных mxArray, который представляет в программах на языке Си матрицы матлаба. Описание аргументов функции mexFunction: nlhs - число возвращаемых в матлаб матриц, plhs - массив адресов матриц (переменные типа mxArray), возвращаемых в матлаб, nrhs - число аргументов, переданных в функцию при вызове из матлаба, prhs - массив адресов матриц, переданных в функцию при вызове из матлаба. В заголовочном файле matrix.h описаны все функции, необходимые для работы с переменными типа mxArray. Приведу лишь наиболее часто употребляемые. Но прежде необходимо отметить, что ряд функций, которые использовались в консольных приложениях, нельзя использовать при вызове функций из матлаба. Это прежде всего функции, содержащиеся в зоголовочных файлах stdio.h и malloc.h. Вместо функции printf необходимо использовать функцию extern int mexPrintf( const char *fmt, /* printf style format */ ... /* any additional arguments */ ); , аргументы которой полностью аналогичны аргументам функции printf. Вместо функции malloc необходимо использовать функцию extern void *mxMalloc( size_t n /* number of bytes */ );. Вместо функции free используется функция extern void mxFree(void *ptr); /* pointer to memory to be freed */ и т.д. Для размещения в памяти новой переменной типа mxArray используется функция extern mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity flag);, где m - число строк матрицы, n - число столбцов, переменная flag принимает два значения: mxREAL - если матрица будет вещественной и mxCOMPLEX - если матрица будет комплексной. Чтобы получить число строк матрицы можно воспользоваться функцией extern int mxGetM( const mxArray *pa /* pointer to array */ );, а для получения числа столбцов функцией extern int mxGetN( const mxArray *pa /* pointer to array */ );. Для получения указателя на первый элемент массива, где хранится вещественная часть матрицы, используется функция extern double *mxGetPr( const mxArray *pa /* pointer to array */ );, а для мнимой части матрицы функция extern double *mxGetPi( const mxArray *pa /* pointer to array */ );. Вещественные и мнимые части матриц хранятся в одномерных массивах по строкам. Для того, чтобы получить номер элемента лежащего в заданой строке и заданном столбце можно воспользоваться функцией extern int mxCalcSingleSubscript(const mxArray *pa, int nsubs, const int *subs);, где nsubs - число элементов в массиве subs, subs[0]- номер строки, subs[1] - номер столбца. Назначить вещественный массив в качестве вещественной части матрицы можно функцией extern void mxSetPr( mxArray *pa, /* pointer to array */ double *pr /* real data array pointer */ );, а для мнимой части функцией extern void mxSetPi( mxArray *pa, /* pointer to array */ double *pr /* imaginary data array pointer */ );. Выполнить в программе на языке Си любую функцию матлаба можно с помощью функции extern int mexCallMATLAB( int nlhs, /* number of expected outputs */ mxArray *plhs[], /* pointer array to outputs */ int nrhs, /* number of inputs */ mxArray *prhs[], /* pointer array to inputs */ const char *fcn_name /* name of function to execute */ ); . Много примеров mex-функций можно найти в директории матлаба %MATLAB%\extern\examples\mex. Самый простой из них содержится в файле mexfunction.c. Для компиляции нужно ввести команду mex mexfunction.c с консоли матлаба или windows. Если в программе нет ошибок и компиляция успешна Вы получите файл mexfunction.dll, который можно запускать из матлаба. /*================================================================= * mexfunction.c * * This example demonstrates how to use mexFunction. It returns * the number of elements for each input argument, providing the * function is called with the same number of output arguments * as input arguments. * This is a MEX-file for MATLAB. * Copyright 1984-2000 The MathWorks, Inc. * All rights reserved. *=================================================================*/ /* $Revision: 1.5 $ */ #include "mex.h" void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) { int i; /* Examine input (right-hand-side) arguments. */ mexPrintf("\nThere are %d right-hand-side argument(s).", nrhs); for (i=0; i<nrhs; i++) { mexPrintf("\n\tInput Arg %i is of type:\t%s ",i,mxGetClassName(prhs[i])); } /* Examine output (left-hand-side) arguments. */ mexPrintf("\n\nThere are %d left-hand-side argument(s).\n", nlhs); if (nlhs > nrhs) mexErrMsgTxt("Cannot specify more outputs than inputs.\n"); for (i=0; i<nlhs; i++) { plhs[i]=mxCreateDoubleMatrix(1,1,mxREAL); *mxGetPr(plhs[i])=mxGetNumberOfElements(prhs[i]); } } Задачи Задача 1. Полиномы Эрмита вычисляются по формулам H(0,x)=1 H(1,x)=2*x H(k,x)=2*x*H(k-1,x) -2*(k-1)*H(k-2,x). Написать mexFunction для вычисления значений первых n+1 полиномов Эрмита для заданного значения x. Вызов в матлабе должен выглядеть примерно так h=Hermit(n,x), где h - вектор столбец из n+1 элемента.previous home