Pliki Mex: jak zwrócić już przydzieloną tablicę Matlab
Znalazłem naprawdę trudny problem, którego nie wydaje mi się łatwo naprawić. Krótko mówiąc, chciałbym zwrócić z pliku mex tablicę, która została przekazana jako wejście funkcji mex. Możesz trywialnie to zrobić:
void mexFunction(int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin[])
{
pargout[0] = pargin[0];
}
Ale tego nie potrzebuję. Chciałbym uzyskać surowy wskaźnik zpargin[0]
, przetwórz go wewnętrznie i zwróć świeżo utworzoną tablicę mex, ustawiając odpowiedni wskaźnik danych. Tak:
#include <mex.h>
void mexFunction(int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin[])
{
mxArray *outp;
double *data;
int m, n;
/* get input array */
data = mxGetData(pargin[0]);
m = mxGetM(pargin[0]);
n = mxGetN(pargin[0]);
/* copy pointer to output array */
outp = mxCreateNumericMatrix(0,0,mxDOUBLE_CLASS,mxREAL);
mxSetM(outp, m);
mxSetN(outp, n);
mxSetData(outp, data);
/* segfaults with or without the below line */
mexMakeMemoryPersistent(data);
pargout[0] = outp;
}
To nie działa. Dostaję segfault, jeśli nie natychmiast, to po kilku telefonach. Uważam, że nic takiego nie mówi się o takim scenariuszuw dokumentacji. Jedynym wymogiem jest kapeluszdata
wskaźnik został przydzielony za pomocąmxCalloc
, co oczywiście ma. Dlatego zakładam, że ten kod jest legalny.
Muszę to zrobić, ponieważ analizuję skomplikowaną strukturę MATLAB w moich wewnętrznych strukturach danych C. Przetwarzam dane, niektóre dane zostają ponownie przydzielone, inne nie. Chciałbym w przejrzysty sposób zwrócić strukturę wyjściową, nie myśląc, kiedy muszę po prostu skopiowaćmxArray
(pierwszy fragment kodu) i kiedy rzeczywiście muszę go utworzyć.
Proszę pomóż!
EDYTOWAĆ
Po dalszym przyjrzeniu się i omówieniu z Amro wydaje się, że nawet mój pierwszy fragment kodu nie jest obsługiwany i może powodować awarie programu MATLAB w pewnych sytuacjach, np. Podczas przekazywania pól struktury lub elementów komórki do takiej funkcji mex:
>> a.field = [1 2 3];
>> b = pargin_to_pargout(a.field); % ok - works and assigns [1 2 3] to b
>> pargin_to_pargout(a.field); % bad - segfault
Wygląda na to, że będę musiał zejść z „nieudokumentowanej drogi MATLAB” i użyćmxCreateSharedDataCopy
imxUnshareArray
.