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

15 visualizaciones (últimos 30 días)
Steven Brossi
Steven Brossi el 31 de Oct. de 2022
Comentada: Steven Brossi el 11 de Sept. de 2023
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?

Respuestas (1)

Maneet Kaur Bagga
Maneet Kaur Bagga el 7 de Sept. de 2023
Editada: Maneet Kaur Bagga el 7 de Sept. de 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 comentario
Steven Brossi
Steven Brossi el 11 de Sept. de 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

Iniciar sesión para comentar.

Categorías

Más información sobre Call C from MATLAB en Help Center y File Exchange.

Productos


Versión

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by