Using a custom deleter in a buffer_ptr_t in ArrayFacto​ry::create​ArrayFromB​uffer

조회 수: 12 (최근 30일)
I would like to use the createArrayFromBuffer method of ArrayFactory in a mex file to create a Matlab array from data which I've previously calculated. However, I want to use a custom deleter rather than a Matlab provided deleter, but createArrayFromBuffer does not respect the deleter function pointer I included. For example, with the mex file below:
#include "mex.hpp"
#include "mexAdapter.hpp"
#include <iostream>
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
matlab::data::ArrayFactory factory;
double *data = new double[9];
for (int i = 0; i < 9; i++) {
data[i] = static_cast<double>(i);
}
buffer_deleter_t deleter = [](void* ptr) { delete(ptr); };
buffer_ptr_t<double> buffer = buffer_ptr_t<double>(data, deleter);
std::cout << "Original buffer address = " << buffer.get() << "\n";
std::cout << "Custom deleter address = " << deleter << "\n";
TypedArray<double> array = factory.createArrayFromBuffer<double>({3, 3}, std::move(buffer));
buffer_ptr_t<double> array_buffer = array.release();
buffer_deleter_t array_deleter = array_buffer.get_deleter();
std::cout << "Released array buffer address = " << array_buffer.get() << "\n";
std::cout << "Created array deleter address = " << array_deleter << "\n";
// We have to assign the memory to an output variable otherwise Matlab will try to delete
// the buffer memory with its own deleter and this causes a heap memory error.
outputs[0] = factory.createArrayFromBuffer<double>({3, 3}, std::move(array_buffer));
}
};
which I've called deleter_example.cpp, I compile with:
mex -g -R2018a deleter_example.cpp
and run with:
>> x = deleter_example
Original buffer address = 000000017F180020
Custom deleter address = 00007FFC0B02BAF0
Released array buffer address = 000000017F180020
Created array deleter address = 000000000EE604E0
x =
0 3 6
1 4 7
2 5 8
So the data array is not copied (which is what I want) but the deleter has been changed.
Also, if I now do:
clear x
Matlab crashes with a heap memory error (in Visual Studio debugging - without debugging it just crashes without any message, not even a "access violation fault"). This crash also happens if the created array is not assigned to outputs[0] so it is deleted when the mex function ends. I think this memory error is because the mex file is compiled with a different compiler than Matlab itself (I'm using Visual Studio 2017) so it has a different heap.
I'm actually calling another library function to calculate something and it returns a raw float array which I want to put back into Matlab. This array could be quite large so I don't want to copy it as would be the case with ArrayFactory::createArray() - is there any way to use createArrayFromBuffer safely for these types of use-cases?

채택된 답변

Krishna Adi
Krishna Adi 2020년 4월 16일
The workflow which you are trying to use is currently not supported.
If your goal is to avoid copying the data, the only way to successfully do that would be for the other library function to use the MATLAB Data API to create the buffer.

추가 답변 (1개)

Mingyu
Mingyu 2024년 9월 17일
Starting R2024b, the createArrayFromBuffer method of ArrayFactory in the MATLAB Data Array (MDA) API supports user-managed buffers. No data copy will be made when creating an MDA from the buffer. You can specify a custom deleter in the buffer to manage the lifetime of the allocated data. The buffer needs to of type
buffer_ptr_t, which is defined as std::unique_ptr<T[], buffer_deleter_t<T>>
The deleter needs to be type
buffer_deleter_t is defined as void (*)(T*)
Please refer to this documentation page for an example on creating a MDA from data that has been allocated by a third-party library: https://www.mathworks.com/help/matlab/matlab_external/manage-buffer-memory-with-custom-deleter-function.html
The MEX function implementation in your question will remain the same when you create a MDA using createArrayFromBuffer with a user-managed buffer. Clearing the last array (which was created from the buffer) in MATLAB will invoke the custom deleter in the provided buffer.

카테고리

Help CenterFile Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

태그

제품


릴리스

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by