Using a custom deleter in a buffer_ptr_t in ArrayFactory::createArrayFromBuffer
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?
0 个评论
采纳的回答
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.
0 个评论
更多回答(1 个)
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.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!