Как создать исходный Mex-файл C

#c #matlab

#c #matlab

Вопрос:

У меня есть программа на C, которая умножает скалярное число на массив. Я хотел бы создать mex-файл для вызова этой функции в MATLAB. Я перешел по этой ссылке, но у меня возникли некоторые проблемы с компиляцией, и мне пришлось изменить часть кода.

Функция C, которую я реализовал, является:

 #include "mex.h"
#include <stdio.h>
#include <stdlib.h>


void arrayProduct(double x, double *y, double *z, int n){
    int i;

    for (i=0;i<n;i  ){
        z[i]=x * y[i];
    }
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){

double multiplier;
double *inMatrix;
mwSize ncols;
double *outMatrix;

multiplier = mxGetScalar(prhs[0]);
#if MX_HAS_INTERLEAVED_COMPLEX
    inMatrix=mxGetDoubles(prhs[1]);
#else
    inMatrix = mxGetPr(prhs[1]);
#endif
ncols=mxGetN(prhs[1]);

plhs[0]=mxCreateDoubleMatrix(1,ncols,mxREAL);

#if MX_HAS_INTERLEAVED_COMPLEX
    outMatrix=mxGetDoubles(plhs[0]);
#else
    outMatrix=mxGetPr(prhs[0]);
#endif
arrayProduct(multiplier,inMatrix,outMatrix,ncols);

if(nrhs != 2){
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","Two inputs required.");
}
if(nlhs != 1){
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","One input required.");
}
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxGetNumberOfElements(prhs[0]) != 1){
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar","Input multiplier must be scalar.");
}


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

Прямо сейчас я могу создать mex-файл (.mexmaci64, я использую macOS), но когда я вызываю функцию arrayProduct(s,A), где s = 5 и A = [1.5,2,9], я получаю это сообщение:

Ошибка при использовании arrayProduct Требуется один ввод.

Как я могу исправить эту ошибку, чтобы сгенерировать правильный mex-файл или правильно запустить функцию?

Любая помощь приветствуется.

Комментарии:

1. Вы написали код, но не знаете, как он работает? Там есть тест, который проверяет количество выходов ( nlhs ), и если оно не равно 1, оно выдает ошибку с этим сообщением, которое вы получаете. Итак, вам нужно его вызвать out = arrayProduct(s,A) .

2. Тем не менее, вы действительно должны переместить эти проверки в начало функции, прежде чем обращаться к данным. Если вы проверите, что данные действительны после их чтения, уже слишком поздно!

3. @Cris Я в целом не согласен, но вы можете назначить plhs[0] , даже если это явно не требуется, как указано здесь: mathworks.com/help/matlab/apiref/mexfunction.html . На самом деле, обычно назначается plhs[0] даже когда nlhs==0 , чтобы избежать странностей, как видно из OP (исключением являются те странные методы, которые имеют шаблон «отображать материал или возвращать материал»).

4. @Edric: Да, plhs[0] всегда существует, этот тест в коде бесполезен (и сообщение, которое он выдает, также неверно). Важно выполнять проверки входных данных. Этот код, скорее всего, приведет к сбою MATLAB при вызове без ввода или с вводом неправильных размеров.

5. Это потому, что вы используете mxGetM для получения количества столбцов (которое вам требуется равным 1), но эта функция возвращает количество строк. Пожалуйста, ознакомьтесь с документацией для функций, которые вы используете.