How do I get a C++ structure 'behind' a libpointer?
14 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Philip Borghesani
2012-3-13
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.
更多回答(3 个)
Ampere Kui
2012-2-19
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 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Call C from MATLAB 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!