How to modify a TypedArray in a structure without modifying the underlying pointer in a mex file?

3 ビュー (過去 30 日間)
I have a mex file which receives a structure which has several fields as input and returns the same structure. One of the fields is a 2D double array.
I can read the data on the specific field, cast is to a TypedArrayRef<double> and modify it. But everytime I look at the structure address behind data (using format debug) in successive executions of the MEX file, the pointer to the array changes. Why is this?
Does this mean the data is being copied? I want to avoid copying the data.
  3 件のコメント
Simon Müller
Simon Müller 2022 年 1 月 31 日
編集済み: Walter Roberson 2022 年 1 月 31 日
Hi @James Tursa, thank you for your answer. I am using exactly the example from here: https://de.mathworks.com/help/matlab/matlab_external/avoid-copies-of-large-arrays.html
So basically I use the following code:
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
checkArguments(inputs);
TypedArray<double> largeArray = std::move(inputs[0]);
for (auto& elem : largeArray) {
if (elem < 0) {
elem = 0;
}
}
outputs[0] = largeArray;
}
void checkArguments(ArgumentList inputs) {
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
ArrayFactory factory;
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getType() == ArrayType::COMPLEX_DOUBLE) {
matlabPtr->feval(u"error", 0,
std::vector<Array>({ factory.createScalar("Incorrect input") }));
}
}
};
I compile it with the mex command and execute it as follows:
format debug
testMatrix = magic(3)
testMatrix =
Structure address = f6d0cf00
m = 3
n = 3
pr = 1193c2e60
8 1 6
3 5 7
4 9 2
Then I run the mex as follows:
testMatrix = removeNegativeNumbers(testMatrix)
testMatrix =
Structure address = f6d0bf20
m = 3
n = 3
pr = 13df6e6e0
8 1 6
3 5 7
4 9 2
So the addresses change. The title of the help suggests there is a way of avoiding copies. Or am I missunderstanding something here?
Simon Müller
Simon Müller 2022 年 2 月 11 日
@James Tursa, Is this possible, or does the MATLAB API not allow something like it?

サインインしてコメントする。

回答 (1 件)

Karan Singh
Karan Singh 2024 年 1 月 30 日
Hi Simon,
The MATLAB Data API, which you're using in the provided C++ MEX example, is designed to be safe and to prevent accidental misuse of memory. When you pass data from MATLAB to a MEX function, MATLAB uses a copy-on-write strategy. This means that the data is not physically copied until you try to modify it. When you access the data in a read-only fashion, you are looking at the original data. However, once you modify the data, MATLAB will create a copy of the data to preserve the original data's integrity.
In the example you've provided, you're modifying the elements of the array with this loop:
for (auto& elem : largeArray) {
if (elem < 0) {
elem = 0;
}
}
Hope this clarifies the doubt!

カテゴリ

Help Center および File ExchangeData Types についてさらに検索

製品


リリース

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by