Создание исходного файла MEX на C

Этот пример показывает, как записать файл MEX, чтобы вызвать функцию C arrayProduct в MATLAB® с помощью массива MATLAB, заданного в Матричном API C. Можно просмотреть полный исходный файл здесь.

Этот пример использует редактора MATLAB, чтобы записать исходный код и команду mex MATLAB, чтобы создать MEX-функцию. Требования для создания файлов MEX перечислены в Исходных Файлах MEX на C. Если вы хотите использовать свою собственную среду разработки C, смотрите Сделанный на заказ с Опциями Скрипта MEX для получения дополнительной информации.

C функционируют arrayProduct

Следующий код задает функцию arrayProduct, которая умножается 1xn матричный y скалярным значением x и возвращает результаты в массиве z. Можно использовать эти те же операторы C в приложении C++.

void arrayProduct(double x, double *y, double *z, int n)
{
  int i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

Создание файла исходного кода

Открытый редактор MATLAB, создайте файл и зарегистрируйте файл MEX со следующей информацией.

/*
 * arrayProduct.c - example in MATLAB External Interfaces
 *
 * Multiplies an input scalar (multiplier) 
 * times a 1xN matrix (inMatrix)
 * and outputs a 1xN matrix (outMatrix)
 *
 * The calling syntax is:
 *
 *		outMatrix = arrayProduct(multiplier, inMatrix)
 *
 * This is a MEX file for MATLAB.
*/

Добавьте заголовочный файл C/C++, mex.h, содержа объявления функции MATLAB API.

#include "mex.h"

Сохраните файл на своем пути MATLAB, например, в c:\work, и назовите его arrayProduct.c. Именем вашего файла MEX является arrayProduct.

Создание стандартной программы шлюза

Каждая программа C имеет функцию main(). MATLAB использует стандартную программу шлюза, mexFunction, как точка входа к функции. Добавьте следующий код mexFunction.

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
/* variable declarations here */

/* code here */
}

Эта таблица описывает входные параметры для mexFunction.

ПараметрОписание
nlhsКоличество вывода (левая сторона) аргументы или размер массива plhs.
plhsМассив выходных аргументов.
nrhsКоличество входа (правая сторона) аргументы или размер массива prhs.
prhsМассив входных параметров.

Верификация ввода MEX-файла и выходные параметры

Проверьте количество аргументов ввода и вывода файла MEX с помощью аргументов nrhs и nlhs.

Чтобы проверять на два входных параметра, multiplier и inMatrix, используют этот код.

if(nrhs != 2) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs",
                      "Two inputs required.");
}

Используйте этот код, чтобы проверять на один выходной аргумент, продукт outMatrix.

if(nlhs != 1) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs",
                      "One output required.");
}

Проверьте типы аргумента с помощью аргументов plhs и prhs. Этот код подтверждает тот multiplier, представленный prhs[0], скаляр.

/* make sure the first input argument is scalar */
if( !mxIsDouble(prhs[0]) || 
     mxIsComplex(prhs[0]) ||
     mxGetNumberOfElements(prhs[0]) != 1 ) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar",
                      "Input multiplier must be a scalar.");
}

Этот код подтверждает тот inMatrix, представленный prhs[1], тип double.

if( !mxIsDouble(prhs[1]) || 
     mxIsComplex(prhs[1])) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble",
        "Input matrix must be type double.");
}

Подтвердите тот inMatrix, вектор - строка.

/* check that number of rows in second input argument is 1 */
if(mxGetM(prhs[1]) != 1) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector",
                      "Input must be a row vector.");
}

Создание стандартной программы вычислительных операций

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

void arrayProduct(double x, double *y, double *z, int n)
{
  int i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

Вычислительная процедура является дополнительной. Также можно поместить код в функциональном блоке mexFunction.

Запись кода для кросс-платформенной гибкости

MATLAB обеспечивает макрос препроцессора, mwsize, который представляет значения размера для целых чисел, на основе платформы. Вычислительная процедура объявляет размер массива как int. Замените объявление int для переменных n и i с mwsize.

void arrayProduct(double x, double *y, double *z, mwSize n)
{
  mwSize i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

Объявление переменных для вычислительной процедуры

Поместите следующие объявления переменной в mexFunction.

  • Объявите переменные для входных параметров.

    double multiplier;      /* input scalar */
    double *inMatrix;       /* 1xN input matrix */
    
  • Объявите ncols для размера входной матрицы.

    mwSize ncols;           /* size of matrix */
    
  • Объявите выходной аргумент, outMatrix.

    double *outMatrix;      /* output matrix */
    

Позже вы присваиваете аргументы mexFunction этим переменным.

Чтение входных данных

Чтобы считать скалярный вход, используйте функцию mxGetScalar.

/* get the value of the scalar input  */
multiplier = mxGetScalar(prhs[0]);

Используйте функцию mxGetDoubles, чтобы указать на входные матричные данные.

/* create a pointer to the real data in the input matrix  */
inMatrix = mxGetDoubles(prhs[1]);

Используйте функцию mxGetN, чтобы получить размер матрицы.

/* get dimensions of the input matrix */
ncols = mxGetN(prhs[1]);

Подготовка выходных данных

Чтобы задать выходной аргумент, plhs[0], используют функцию mxCreateDoubleMatrix.

/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);

Используйте функцию mxGetDoubles, чтобы присвоить аргумент outMatrix plhs[0]

/* get a pointer to the real data in the output matrix */
outMatrix = mxGetDoubles(plhs[0]);

Выполнение вычислений

Передайте аргументы arrayProduct.

/* call the computational routine */
arrayProduct(multiplier,inMatrix,outMatrix,ncols);

Просмотр всего файла исходного кода

Сравните свой исходный файл с arrayProduct.c, расположенным в matlabroot/extern/examples/mex. Откройте файл arrayProduct.c в редакторе.

Для примера файла MEX C++ с помощью MATLAB Data API смотрите arrayProduct.cpp. Для получения информации о создании файлов MEX с этим API смотрите MEX-функции C++.

Создайте MEX-функцию

В подсказке команды MATLAB создайте функцию с командой mex.

mex arrayProduct.c -R2018a

Протестируйте MEX-функцию

s = 5; 
A = [1.5, 2, 9];
B = arrayProduct(s,A)
B =
    7.5000   10.0000   45.0000 

Проверка входных параметров файла MEX

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

s = 5; 
A = [1.5, 2, 9];
inputArg = int16(A);
if ~strcmp(class(inputArg),'double')
    inputArg = double(inputArg);
end
B = arrayProduct(s,inputArg)

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

| | | | | |

Похожие темы