Advancing a structure pointer in calllib - shared library

조회 수: 6 (최근 30일)
Ricky
Ricky 2011년 10월 4일
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 1x1 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?

채택된 답변

Philip Borghesani
Philip Borghesani 2011년 10월 5일
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.
  댓글 수: 1
Ricky
Ricky 2011년 10월 5일
Hi Philip - Thanks for your response! I think that did it. Looks like the main problem i was having was just as you said - that I should not have output arguments from the calllib statement.
I now just have
calllib('sdfifc','fwifc_read',fileptr,time_sorg,time_ext,originptr,dirptr,flags,facet,sbl_count,sbl_size,sblptr);
sblptr.Value
nextdatablock = sblptr+1;
nextdatablock.Value
block3 = nextdatablock+1;
block3.Value
..and that manages to get everything i need. Thanks again!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Call C from MATLAB에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by