MATLAB: Advancing a structure pointer in calllib – shared library

shared library

I have used loadlibrary to load a .dll and header (.h) file. The function 'fwifc_read' (see below) uses a structure pointer to read data blocks. I am able to read the first data block without a problem. However, I need to advance the pointer to read the next data block. Calling 'fwifc_read' again does not work – simply rereads the first data block. Essentially the problem is that the 'sblptr' below is returned as a 1×1 structure when it should be an nx1 structure.
loadlibrary('sdfifc.dll', @sdfifc)
fileptr = libpointer('fwifc_file_tPtr');
sdffile='blah.sdf';
[a,b,c]=calllib('sdfifc','fwifc_open',sdffile,fileptr);
[bok, fptr] = calllib('sdfifc', 'fwifc_seek', fileptr, 1);
originptr = libpointer('doublePtr', double([0 0 0])); %Origin vector pointer
dirptr = libpointer('doublePtr', double([0 0 0])); %Pulse direction pointer
%Sample block pointer
sblptr = libpointer('fwifc_sbl_struct');
time_sorg = libpointer('doublePtr',double(0));
time_ext = libpointer('doublePtr',double(0));
flags = libpointer('uint16Ptr',uint16(0));
facet = libpointer('uint16Ptr',uint16(0));
sbl_count = libpointer('uint32Ptr',uint32(0));
sbl_size = libpointer('uint32Ptr',uint32(0));
[bok, fptr, time_sorg, time_ext, originptr, dirptr, flags, facet, sbl_count, sbl_size, sblptr] = ... calllib('sdfifc','fwifc_read',fileptr,time_sorg,time_ext,originptr,dirptr,flags,facet,sbl_count,sbl_size,sblptr);
Here is the sdfifc prototype file:
function [methodinfo,structs,enuminfo,ThunkLibName]=sdfifc
%SDFIFC Create structures to define interfaces found in 'fwifc'.
%This function was generated by loadlibrary.m parser version 1.1.6.29 on Tue Oct 4 11:38:41 2011
%perl options:'fwifc.i -outfile=sdfifc.m'
ival={cell(1,0)}; % change 0 to the actual number of functions to preallocate the data.
structs=[];enuminfo=[];fcnNum=1;
fcns=struct('name',ival,'calltype',ival,'LHS',ival,'RHS',ival,'alias',ival);
ThunkLibName=[];
% fwifc_int32_t fwifc_get_library_version ( fwifc_uint16_t * api_major , fwifc_uint16_t * api_minor , fwifc_csz * build_version , fwifc_csz * build_tag );
fcns.name{fcnNum}='fwifc_get_library_version'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'uint16Ptr', 'uint16Ptr', 'cstringPtr', 'cstringPtr'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_get_last_error ( fwifc_csz * message );
fcns.name{fcnNum}='fwifc_get_last_error'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'cstringPtr'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_open ( fwifc_csz path , fwifc_file * file );
fcns.name{fcnNum}='fwifc_open'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'cstring', 'fwifc_file_tPtrPtr'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_close ( fwifc_file file );
fcns.name{fcnNum}='fwifc_close'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'fwifc_file_tPtr'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_reindex ( fwifc_file file );
fcns.name{fcnNum}='fwifc_reindex'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'fwifc_file_tPtr'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_seek_time ( fwifc_file file , fwifc_float64_t time );
fcns.name{fcnNum}='fwifc_seek_time'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'fwifc_file_tPtr', 'double'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_seek_time_external ( fwifc_file file , fwifc_float64_t time );
fcns.name{fcnNum}='fwifc_seek_time_external'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'fwifc_file_tPtr', 'double'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_seek ( fwifc_file file , fwifc_uint32_t record );
fcns.name{fcnNum}='fwifc_seek'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'fwifc_file_tPtr', 'uint32'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_tell ( fwifc_file file , fwifc_uint32_t * record );
fcns.name{fcnNum}='fwifc_tell'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'fwifc_file_tPtr', 'uint32Ptr'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_get_info ( fwifc_file file , fwifc_csz * instrument , fwifc_csz * serial , fwifc_csz * epoch , fwifc_float64_t * v_group , fwifc_float64_t * sampling_time , fwifc_uint16_t * flags , fwifc_uint16_t * num_facets );
fcns.name{fcnNum}='fwifc_get_info'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'fwifc_file_tPtr', 'cstringPtr', 'cstringPtr', 'cstringPtr', 'doublePtr', 'doublePtr', 'uint16Ptr', 'uint16Ptr'};fcnNum=fcnNum+1;
% fwifc_int32_t fwifc_read ( fwifc_file file , fwifc_float64_t * time_sorg , fwifc_float64_t * time_external , fwifc_float64_t * origin , fwifc_float64_t * direction , fwifc_uint16_t * flags , fwifc_uint16_t * facet , fwifc_uint32_t * sbl_count , fwifc_uint32_t * sbl_size , fwifc_sbl_t * * sbl );
fcns.name{fcnNum}='fwifc_read'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'fwifc_file_tPtr', 'doublePtr', 'doublePtr', 'doublePtr', 'doublePtr', 'uint16Ptr', 'uint16Ptr', 'uint32Ptr', 'uint32Ptr', 'fwifc_sbl_structPtrPtr'};fcnNum=fcnNum+1;
structs.fwifc_sbl_struct.members=struct('time_sosbl', 'double', 'channel', 'uint32', 'sample_count', 'uint32', 'sample_size', 'uint32', 'sample', 'uint16Ptr');
structs.fwifc_file_t.members=struct('');
methodinfo=fcns;
For reference, in C++ code, there is a simple advance of the data block
psbl++;
where
fwifc_sbl_t* psbl_first; /* pointer to first sample block */
fwifc_sbl_t* psbl = psbl_first;
Any ideas on how to do that pointer advance in Matlab?

Best Answer

If you are using R2009a or later then you can increment your pointer like so:
nextDataBlock=sblptr+1;
nextDataBlock=nextDataBlock+1;
% or
dataBlockN=sblptr+N;
I suggest minimizing use of the same pointer variables on both sides of a calllib statement. When libpointer objects are used as inputs they are modified in place and no output argument is needed. Libpointer objects should not be needed for the arguments to fwifc_read that are single pointers for those that may be modified by the call the return value can be examined.