exponenta event banner

Создать файл C Source MEX

В этом примере показано, как записать файл MEX для вызова функции C arrayProduct в MATLAB ® с использованием массива MATLAB, определенного в C Matrix API. Полный исходный файл можно просмотреть здесь.

Для использования этого примера необходимо:

  • Возможность записи исходного кода C или C++. Эти файлы создаются с помощью редактора MATLAB.

  • Компилятор, поддерживаемый MATLAB. Обновленный список поддерживаемых компиляторов см. на веб-сайте Поддерживаемые и совместимые компиляторы.

  • Функции в C Matrix API и C MEX API.

  • mex сценарий построения.

Если вы хотите использовать собственную среду разработки 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, содержащий объявления функций API MATLAB.

#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 в редакторе.

Пример файла C++ MEX с использованием API данных MATLAB см. в разделе arrayProduct.cpp. Сведения о создании файлов MEX с помощью этого API см. в разделе Функции C++ MEX.

Функция построения 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

Перед вызовом функции MEX рекомендуется проверить тип переменной MATLAB. Чтобы проверить входную переменную, 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)

См. также

| | | | | |

Связанные темы