Converting Matlab-struct to C-struct and access byte data

33 views (last 30 days)
When calling a shared library (dll) Matlab is very capable in converting structs (except those containing unions and arrays where the size is defined by a -D-flag to the compiler) from the Matlab format to the C-format given in a header file.
Now, in Matlab I have a proprietary library to send byte data (actually 32-bit words...) over via Java sockets to communicate with a mailbox on an embedded system we make. The protocol in our product dictates that a C-struct shall be sent over. What I then would like to do is make Matlab convert my Matlab-struct to a C-struct and then give me the byte data to send to the proprietary library (and the opposite). Is there a way to do this?
Obviously, Matlab knows how to convert to and from C-structs, but how can I access that data in a binary fashion in Matlab?
I have failed so far and been forced to do an ugly hack where I create a dll function that takes a struct and copies it to a byte array which is then returned to Matlab. But I then need to write one such function for each struct I need to transfer. And then I need to write as many functions for converting them from byte arrays to structs. We will probably end up with hundreds of functions so this does not feel like a good solution in the long run.
Any ideas how to skip the dll in my workflow?

Accepted Answer

Philip Borghesani
Philip Borghesani on 20 Jun 2012
This is still a hack but you should be able to create one function in a dll that takes a void * and size as an input and returns an mxArray*. You should then be able to call this function:
bytearray=calllib('mylib','myfun','copyToByte',mystruct,structsize(mystruct))
I do not have a good solution for the reverse function feel free to enter a MATLAB enhancement request for a typecast or equivalent method for libstruct objects. This is a known limitation but you are the first customer I know of that as asked for this feature.
  3 Comments
Tomas Björklund
Tomas Björklund on 21 Jun 2012
I have now asked the your senior account manager Peter Moberg allocated to us for help in filing an enhancement request for a workflow that looks like this:
1. Load a C header file in a similar manner to loading a library (but with only an .h-file and without a .dll file).
2. Convert a Matlab struct to a C-struct given in the header file.
3. Typecast C-struct to binary data (uint8, uint16, uint32 etc).
Philip Borghesani
Philip Borghesani on 21 Jun 2012
structsize is a method on libstruct objects. Create a libstruct object and call methods on it and you should see the method or just try it. If you search help you should find an example of it's use I found it via google...

Sign in to comment.

More Answers (2)

Jed
Jed on 20 Sep 2013
I had a similar requirement, and figured there had to be a straightforward way to do this without needing to create a shared library function just to copy bytes around. It turns out that libpointer already includes the necessary functionality -- there's no need to create a special library function just to do this conversion -- as long as your structures don't include things like bitfields or strange packing requirements (though #pragma pack() seems to be handled OK).
Just create a "void pointer" pointing to a libstruct object, set the data type to 'uint8Ptr', and set the size appropriately. Then all you have to do is query the Value of the libpointer object.
For example, assuming that you've loaded a library/header using loadlibrary which defines a "SensorImageInfo" structure:
// Structure defined in library's .h file
struct SensorImageInfo {
int32 bytes; // Data size, in bytes
uint16 width; // Image Columns (width)
uint16 height; // Image Rows (height)
uint8 bands; // 1 = grayscale, 3 = color (e.g. RGB)
uint8 depth; // Number of bits per pixel
};
Once you've imported the structure definitions into MATLAB (e.g. with loadlibrary), you can do something like the following:
% Populate your data structure
image_info.width = 640;
image_info.height = 480;
image_info.bands = 1;
image_info.depth = 8;
image_info.bytes = 640*480;
% Now convert the MATLAB struct to a C-struct and retrieve the underlying bytes:
sp = libstruct('SensorImageInfo',image_info); % create a libstruct object
vp = libpointer('voidPtr',sp); % create an untyped pointer to the structure
setdatatype(vp, 'uint8Ptr', 1, structsize(sp)); % set the pointer type and size
bytes = vp.Value; % query for the underlying bytes
This results in the following 12 bytes (note that the C struct fields are stored little-endian on this machine, with 10 bytes of actual data plus 2 bytes of tail-padding):
bytes =
0 176 4 0 128 2 224 1 1 8 0 0
  1 Comment
Bram Surewaard
Bram Surewaard on 10 Aug 2020
Could you maybe explain in more detail what your c files would need to look like to make this work and how exactly you load in the files?
This is probably basic knowledge but I have been stuck on this problem for quite a while now and could realy use some help!
Thank!

Sign in to comment.


Walter Roberson
Walter Roberson on 20 Jun 2012
Have you considered using typecast() to coerce your 32 bit words into arrays of uint8 ?
  1 Comment
Tomas Björklund
Tomas Björklund on 20 Jun 2012
The 32 bit to 8 bit conversion is NOT the problem. The problem is converting a Matlab-struct to a C-struct without using a dll-file.

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!