How do I get a C++ structure 'behind' a libpointer?
14 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hi there
I'm using an old 7.5.0/R2007b version of Matlab, and I'm experiencing a problem when reading structures created by an external C++ function.
I'm calling the function
struct_new* GetStruct_new(uint16 const val);
via loadlibrary and calllib. I'm also using a prototype file to circumvent a packing problem I had some months ago.
The structure is declared as follows in C++ code:
typedef struct
{
float32 u16_Upper;
float32 u16_Lower;
float32* pf32_Parameters;
}
match_s;
typedef struct
{
uint16 u16_Start;
uint16 u16_End;
match_s* ps_1st_Match;
match_s* ps_2nd_Match;
}
results_s;
typedef struct
{
uint16 u16_Depth;
uint16 u16_Width;
uint16 u16_Height;
uint16* pu16_InData;
uint16* pu16_OutData;
results_s s_Results[256];
uint8 bla[256];
uint8* blubb[256];
}
struct_new;
...and in the prototype file:
structs.match_s.packing=4;
structs.match_s.members=struct('u16_ED_Upper', 'single', 'u16_ED_Lower', 'single', 'pf32_ED_Parameters', 'singlePtr');
structs.results_s.packing=4;
structs.results_s.members=struct('u16_Start', 'uint16', 'u16_End', 'uint16', 'ps_1st_Match', 'match_sPtr', 'ps_2nd_Match', 'match_sPtr');
structs.struct_new.packing=4;
structs.struct_new.members=struct('u16_Depth', 'uint16', 'u16_Width', 'uint16', 'u16_Height', 'uint16', 'pu16_InData', 'uint16Ptr', 'pu16_OutData', 'uint16Ptr', 's_Results', 'results_s#256', 'bla', 'uint8#256', 'blubb', 'uint8Ptr#256');
In Matlab I do the following:
>> addpath ('\\projects\Binford\KX-2500\')
>> loadlibrary ('KX_drives.dll', @KX-2500, 'alias', 'KX');
>> params = calllib('KX', 'GetStruct_new', 11);
>> par = get(params, 'Value');
>> par.s_Results
ans =
libpointer
This libpointer is my problem, as I have no clue how to resolve it into an array of s_Result structures and read/write them. I've searched the documentation, but I wasn't able to find something that could help me on this one; most exapmles were about creating pointers, not the opposite way.
Thanks in advance!
0 commentaires
Réponse acceptée
Philip Borghesani
le 13 Mar 2012
Given:
structs.struct_new.members=struct('u16_Depth', 'uint16', 'u16_Width', 'uint16', 'u16_Height', 'uint16', 'pu16_InData', 'uint16Ptr', 'pu16_OutData', 'uint16Ptr', 's_Results', 'results_s#256', 'bla', 'uint8#256', 'blubb', 'uint8Ptr#256');
I expect you are getting some warnings when you call loadlibrary. Loadlibrary cannot properly process 'results_s#256' or 'uint8Ptr#256 your options are to redeclare these fields as a vector of a basic data type or change your structure.
For structures this complex you may be better off with a mex file or writing a helper dll that can access the structure and return its members or pointers to the desired members.
Plus de réponses (3)
Ampere Kui
le 19 Fév 2012
You will need to cast the data into something that Matlab can understand.
addpath ('\\projects\Binford\KX-2500\')
loadlibrary ('KX_drives.dll', @KX-2500, 'alias', 'KX');
params = calllib('KX', 'GetStruct_new', 11);
par = get(params, 'Value');
tmp = par.s_Results;
% Assuming setdatatype works on variable tmp.
setdatatype(tmp, 'uint8Ptr');
% The struct s_Results has the following data structure:
% 2 bytes
% 2 bytes
% 4 bytes memory address (8 bytes if you are on 64-bit system)
% 4 bytes memory address (8 bytes if you are on 64-bit system)
m = getfield(libstruct('results_s'), structsize);
bytes = numel(tmp.value);
n = bytes /m;
% Resize the output so that each column corresponds to one structure.
v = reshape(tmp.value, m, n);
% Obtain all the u16_Start and u16_End variables. Note that you won't be able to get libpointer to ps_1st_Match and ps_wnd_Match this way.
toVector = @(x) x(:);
u16_Start = typecast(toVector(v(1:2,:)), 'uint16');
u16_End = typecast(toVector(v(3:4,:)), 'uint16');
Alternately, you can copy each column into a libstruct of type results_s to obtain the entire structure. If you have a function foo() that returns a pointer to one results_s structure, then you can try this:
% Copy one column of data from v to the libpointer from foo().
s = calllib('KX', 'foo');
setdatatype(s, 'uint8Ptr');
s.value = v(:,1);
setdatatype(s, 'results_sPtr');
% The structure in the first cell of the array:
disp(s.value);
0 commentaires
Kaustubha Govind
le 19 Déc 2011
Do you get anything useful by trying:
par.s_Results.Value;
0 commentaires
Voir également
Catégories
En savoir plus sur Call C from MATLAB dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!