C++ (DLL) interface: How to return variable size c-array

17 views (last 30 days)
I have a function (C/C++) that returns a pointer to an array of variable size. E.g. like this:
DLL_EXPORT uint8_t* getBuffer(int* len) {
size_t l = 512;
uint8_t* dummyBuffer = new uint8_t[l];
*len = l;
return dummyBuffer;
}
I assumed that I can define "len" as output argument and then use this as SHAPE for the output definition:
%% C++ function |getBuffer| with MATLAB name |clib.MyLib.getBuffer|
% C++ Signature: uint8_t * getBuffer(int * len)
getBufferDefinition = addFunction(libDef, ...
"uint8_t * getBuffer(int * len)", ...
"MATLABName", "clib.MyLib.getBuffer", ...
"Description", "clib.MyLib.getBuffer Representation of C++ function getBuffer."); % Modify help description values as needed.
defineArgument(getBufferDefinition, "len", "int32", "output", 1); % <MLTYPE> can be "clib.array.MyLib.Int", or "int32"
defineOutput(getBufferDefinition, "RetVal", "uint8", "len");
validate(getBufferDefinition);
Unforunately this gives the follwing error when running the defineMyLib.m script:
Error using clibgen.FunctionDefinition/defineOutput
Invalid shape 'len'. Shape value 'len' is not an integer type. Set shape to an array of one or more
argument names or fixed values of integer type representing the dimensions of 'RetVal'.
Is there a trick to slove this? (I guess, I could split this in two calls: First call to get the length, second call to get the pointer passing len as input argument. But this is obviously very ugly.)
How can a function return a variable-length c-array?

Answers (1)

Maneet Kaur Bagga
Maneet Kaur Bagga on 7 Sep 2023
Edited: Maneet Kaur Bagga on 7 Sep 2023
Hi Steven Brossi,
As per my understanding of the question, to handle the variable length C-array you may use the following suggested methods:
  • Create an opaque object to hold the length, then call the function to retrieve the length.
len = coder.opaque('int32_T', '0'); % Create an opaque object to hold the length
clib.MyLib.getBuffer(len); % Call the function to retrieve the length
% Convert the length to a MATLAB variable
lenValue = int32(len);
  • Using a libpointer to create a pointer object lenof type int32Ptr to hold the length value and then call the function to retrieve the length.
% Call the function to get the length
len = libpointer('int32Ptr', 0);
clib.MyLib.getBuffer(len);
% Retrieve the length value
lenValue = len.Value;
You may also use "calllib" function with the "libpointer" function to first load the library functions and then call them to retrieve the value.
After retrieving the value of len from the above suggested methods you may create a buffer MATLAB Array and then call the function again with lenValue as the argument to get the bufferArray store the actual values.
% Allocate a MATLAB array
bufferArray = zeros(1, lenValue, 'uint8');
You may refer to the following MATLAB Documentation for better understanding of the functions above:
opaque object
libpointer function
calllib function
I hope this helps!
Thank You
Maneet Bagga
  1 Comment
Steven Brossi
Steven Brossi on 11 Sep 2023
Dear Maneet Bagga
Thank you for the detailed suggestions. I have solved it by splitting the the interface into two functions, one for getting the length and one for getting the pointer. To my understanding all you suggestions also need two calls.
It's a bit sad that this is not possible in one call because especailly in C, I see these kind of interface every now and then.
Regards,
Steven

Sign in to comment.

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!