#matlab #mex
#matlab #mex
Вопрос:
Привет, я действительно не понимаю, как получить доступ к данным, передаваемым через аргументы в matlab в mex-функцию. Предполагая, что у меня есть функция шлюза по умолчанию
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
И теперь я получаю указатель на аргумент 1. input:
double* data_in;
data_in = mxGetPr(prhs[0]);
Обе следующие строки, каждая отдельно, приводят к сбою моего matlab:
mexPrintf("%d", *data_in);
mexPrintf("%d", data_in[1]);
Но почему я не могу получить доступ к данным таким образом, когда data_in, очевидно, является указателем на первый аргумент?
- Когда мне нужно объявлять указатель как double *, а когда как mxArray *? Иногда я вижу что-то вроде этого: mxArray *arr = mxCreateDoubleMatrix(n, m, mxREAL);!?
Заранее большое спасибо!
Ответ №1:
data_in
является указателем на double
, поэтому вам нужно что-то вроде
mexPrintf("%f", data_in[0]);
Предполагается, что вызывающий объект передал вектор или матрицу размером > 0.
В более общем плане, вы можете
int n = mxGetN(array);
int m = mxGetM(array);
Чтобы получить количество строк и столбцов матрицы / вектора, переданных в функцию mex.
Что касается mxArray
:
Matlab упаковывает свои матрицы (сложные и вещественные) в структуру mxArray. mxCreateDoubleMatrix
возвращает указатель на такую структуру. Чтобы фактически получить доступ к этим данным, вам нужно использовать mxGetPr () для действительной части и mxGetPi () для мнимых частей.
Они возвращают указатели на выделенные double[]
массивы, которые вы можете использовать для доступа (чтения и записи) к элементам матрицы.
Комментарии:
1. Да, я тоже так думал, но когда я использую
mexPrintf("%f", data_in1[0]);
в своем mexfile, это приводит к сбою matlab…: «———————————————————————— Нарушение сегментации обнаружено в чт, апрель 28 11:45:00 2011 ————————————————————————»2. @bjoern: убедитесь, что указатель, возвращаемый из mxGetPr, не равен нулю (0) и что mxGetN и mxGetM возвращают числа >= 1
3. Хорошо, спасибо, теперь это работает хорошо! Но у меня есть еще один вопрос: предполагая, что я передаю матрицу через myfunction([1:2; 3:4]) Интересно, почему я не могу получить доступ к данным подобным образом (после
in = mxGetPr(prhs[0]);
):mexPrintf("%f", in[0][0]);
вместо этого я должен использовать ‘single’-индексирование подобным образом: в [3] вернет 4, а в[0] вернет 1. Почему нет более «очевидной» двойной индексации, как в [n] [m]?4. @bjoern: Вы можете получить доступ к массиву в C, используя обозначение x [строка] [столбец], только если компилятор знает количество столбцов в строке во время компиляции (поэтому он может переписать это как x [строка * элемент_пер_роу столбец]). Поскольку размерность массива Matlab заранее неизвестна, вы не можете использовать обозначение x[][]. Если вы пишете c , вы можете обернуть mx_array в класс и изменить подходящий operator(), чтобы вы могли получать доступ к элементам, таким как x (строка, столбец).
5. Так это действительно поведение, каким оно должно быть? 🙂
Ответ №2:
Очень удобным способом обработки измерений mxArrays является введение функции, подобной следующей.
#include <cstddef>
#include <cstdarg>
#include "mex.h"
bool mxCheckDimensions(const mxArray* mx_array, size_t n_dim,...) {
va_list ap; /* varargs list traverser */
size_t *dims; /* dimension list */
size_t i;
size_t dim;
bool retval = true;
va_start(ap,n_dim);
dims = (size_t *) malloc(n_dim*sizeof(size_t));
for(i=0;i<n_dim;i ) {
dims[i] = va_arg(ap,size_t);
dim = mxGetDimensions(mx_array)[i];
if (dim != dims[i])
retval = false;
}
va_end(ap);
free(dims);
return retval;
}
Таким образом, вы проверяете, является ли массив mxArray * p двойным массивом размером, скажем, 1,3, используя
double* pDouble = NULL;
if (mxIsDouble(p)) {
if (mxCheckDimensions(p, 2, 1, 3)) {
pDouble = (double*) GetData(p);
// Do whatever
}
}`