Using a custom deleter in a buffer_ptr_t in ArrayFactory::createArrayFromBuffer
显示 更早的评论
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?
采纳的回答
更多回答(1 个)
Mingyu
2024-9-17
1 个投票
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.
类别
在 帮助中心 和 File Exchange 中查找有关 Write C++ Functions Callable from MATLAB (MEX Files) 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!