Здесь много вопросов. Прежде всего, вы приводите указатель на double
, который не сохраняет его представление:
uintptr_t c_value = (uintptr_t)c;
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
*mxGetPr(plhs[0]) = c_value; // return pointer to matlab environment
Вместо этого создайте 64-битный целочисленный массив для сохранения указателя на:
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);
*(uint64_t*)mxGetData(plhs[0]) = (uint64_t)c;
(Поскольку у MATLAB R2018a есть альтернатив mxGetData
для каждого типа , в этом случае это будет mxGetUint64s
).
Во-вторых, память new
ed, вероятно, будет удалена при выгрузке MEX-файла. Это может произойти в любое время. Чтобы предотвратить это, заблокируйте MEX-файл в памяти, используя mexLock
. Чтобы предотвратить утечки памяти, вам нужно будет включить код, который удаляет память, когда вы закончите с ней. Поскольку ваш MATLAB-класс является классом-дескриптором, это может быть достигнуто.
В-третьих, очень просто вызвать MEX-файл с неверным указателем, что, вероятно, приведет к краху всей MATLAB. С вашей текущей реализацией это никак не обойтись.
В-четвертых, как указано Navan , следующая строка создает копию строки, но в буфере памяти, поддерживаемом MATLAB:
fn = mxArrayToString(prhs[1]);
MATLAB автоматически удалит всю память, выделенную на mxMalloc
и аналогичную в конце mexFunction
. Таким образом, fn
будет указывать на свободную память. Вам нужно вручную создать копию здесь, в памяти, которой вы управляете. Я предлагаю вам скопировать строку в std::string
вместо:
class CABAC {
public:
std::string fn;
};
fn = mxArrayToString(prhs[1]); // Will copy the string to `fn`.
Однако вместо этого я бы рекомендовал другой подход:
- В вашем MEX-файле храните массив указателей на выделенные объекты.
- MEX-файл не возвращает указатель, а возвращает индекс массива.
- MEX-файл теперь может проверять входной «дескриптор», чтобы он находился в пределах допустимых границ массива, а также, содержит ли этот массив действительный указатель или указатель
NULL
(например, для удаленного объекта или для элемента массива, который еще не использовался).
- Заблокировать MEX-файл, но разрешить команде разблокировать его. Разблокировка MEX-файла также приведет к удалению всех выделенных объектов.
- Вы можете включить логику для автоматической разблокировки MEX-файла, когда последний из выделенных объектов был удален.
Вы должны знать, что глобальные переменные будут сохраняться между обращениями к MEX-файлу (пока он заблокирован). Таким образом, вам понадобится глобальный массив (определенный вне mexFunction
) для хранения указателей. В качестве альтернативы, объявите массив static
внутри mexFunction
.
Этот MEX-файл реализует рекомендацию, описанную здесь, хотя это далеко не тривиальный пример, я надеюсь, что он может быть полезен в качестве отправной точки. В этой функции я использую std::map
вместо обычного массива для хранения дескрипторов.