#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), но эта функция возвращает количество строк. Пожалуйста, ознакомьтесь с документацией для функций, которые вы используете.