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.

questionAnswers(2)

yourAnswerToTheQuestion