MATLAB: How to use a structure that contains pointers with a generic DLL function in MATLAB

arraydllgenericinterfacelibrarylibstructloadlibraryMATLABpointersharedshlibstructstructure

I am using MATLAB’s generic DLL interface functions to load a DLL. One of my DLL functions takes as an input a user-defined C structure, of which one of the fields is a pointer. For example, my C structure might be defined as:
 
struct my_struct {
long size_a1;
unsigned char *a1;
long size_a2;
double *a2;
};
I have some functions:
 
void allocateStruct(struct my_struct** val)
void readMyStruct(struct my_struct val)
When I attempt to examine the values of the structure returned by allocateStruct, I get:
  ERROR: ??? The datatype and size of the value must be defined before the value can be retrieved.
Also, if I create the structure in MATLAB using LIBSTRUCT and attempt to set the value of a1, I get an error: ERROR: ??? Array must be numeric or logical or a pointer to one.

Best Answer

When using C structures which contain elements to pointers, one must consider that the memory for the data that the pointer points to is allocated separately from the structure.
If the structure is returned to MATLAB from a shared library function call, you will need to set the data type and size of the pointer members of the structure. For example:
 
sp=libpointer('my_structPtr')
calllib('structsample', 'allocateStruct', sp)
setdatatype(sp.Value.a1,'uint8Ptr',1,sp.Value.size_a1)
setdatatype(sp.a2,'doublePtr',1,size_a2)
Data pointed at by the structure can now be accessed. Note that for the character data, you need to convert the raw ASCII values to printable characters using the CHAR function.
 
char(sp.Value.a1)
sp.Value.a2
When passing a structure to a shared library function, the members of the structure need to be initialized. For example:
 
s.a1=uint8(['hi' 0]);
s.size_a1=length(s.a1)
s.a2=1:0.1:10
s.size_a2=length(s.a2)
get(s)
calllib('structsample', 'readMyStruct', s)
Note: Character data needs to be converted to integer data in order to be assigned to the "a1" char pointer data member.