how to read strings with multiple null (\0) terminators when using calllib functions

7 ビュー (過去 30 日間)
Hi everyone,
I've got a problem reading data from a device using external C dlls and calllib function.
The alias .m header file is something as below:
int ws_read_configdata ( const char * name , char * buffer , int buffersize , int * nread );
% fcns.name{fcnNum}='ws_read_configdata'; fcns.calltype{fcnNum}='cdecl'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'cstring', 'cstring', 'int32', 'int32Ptr'};fcnNum=fcnNum+1;
or in the real .h file, as:
% *@param name [in] Previously created WaveShaper name
% *@param buffer [out] buffer to hold configuration data
% *@param buffersize [in] buffer size
% *@param nread [out] configuration data read in bytes
% *@return status code
% */
% int ws_read_configdata(const char* name, char* buffer, int buffersize, int* nread);
The matlab code I used to retrieve the data from the device is like:
bufsize = 10000000;
bufread = 0;
buf = blanks(bufsize);
[rc, a, b, c] = calllib(libname, 'ws_read_configdata', wsname, bufptr, bufsize, 0);
which returns me in variable b, only the first eight CHARS ['37CB39A6']. The remaining of the data is unreachable. The other returned values are shown below
rc = 0; % error check code, 0 = success
a = 58113; % serial number of device
b = '37CB39A6'; % returned data, WRONG! ONLY FIRST EIGHT CHARS
d = 6061152; % bytes that have been read
when I tried to use libpointers like:
bufsize = 10000000;
bufread = libpointer('int32Ptr', bufsize);
buf = blanks(bufsize);
bufptr = libpointer('string', buf);
[rc, a, bufptr.value, c] = calllib(libname, 'ws_read_configdata', wsname, bufptr, bufsize, bufread);
the problem remains the same.
rc = 0;
a = 58113;
bufptr.value = '37CB39A6';
c = 6061152;
yet now
bufread.value = 6061152
The content retrieved data by other methods (using executable file) is like
that is to say, the there are \0 characters in the data.
Any ideas how can I deal with this issue?
Thanks
Deming

採用された回答

Philip Borghesani
Philip Borghesani 2017 年 3 月 23 日
Modify the prototype m file to declare the buffer variable as int8Ptr (or uint8Ptr) instead of cstring. Then pass an int8 buffer:
bufptr = libpointer('int8Ptr', zeros(bufsize,1,'int8'));
[rc, ~, ~ , c] = calllib(libname, 'ws_read_configdata', wsname, bufptr, bufsize, 0);
bufptr.value
If you want the results in a character array you can convert with the char function. bufferwithnulls=char(bufptr.value)
  2 件のコメント
Deming Kong
Deming Kong 2017 年 3 月 23 日
Hi Philip,
Thank you very much for your prompt answer. It just worked like magic! :) I really appreciate it.
BR, Deming
Thomas Carpenter
Thomas Carpenter 2022 年 12 月 15 日
Is there any way to force MATLAB to force MATLAB to detect int8 rather than as cstring? It seems like a horrible hack having th change the API entry definitions in my DLL file to the wrong data type (affects other software that uses the DLL) just because MATLAB does bizarre things.
We used to use LPSTR from Windows.h which MATLAB would sometimes pick up as int8Ptr rather than cString (even though LPSTR is literally a typedef for char*) - not always though! However that works only intermittently to force the issue and is no good if you also need to support Linux compiles (unless we start having compatibility headers with random type defines which is just ugly).
When it was picking things up as int8Ptr our code worked fine, but having recently changed the API to char* to support Linux nicely, it's suddenly broken everything in obscure ways. For example if you have an API that's say:
void populateBuf(char* buf, int bufLen)
Which will fill up to bufLen characters into the buffer buf.
Then call it from MATLAB with:
bufIn = char(zeros(1,10,'int8')); % Just an example, can be any array with nulls in it.
result = calllib('populateBuf', bufIn, 10);
When it was int8Ptr it would work absolutely fine. However when it detects as cString MATLAB will hard fault from heap corruption even through the DLL wrote <10 characters into a buffer which is supposed to be 10 characters long. MATLAB appears to have truncated the buffer at the first null character and passed in a non-null pointer to a zero-length buffer (on return MATLAB tries to free this buffer and corrupts its memory space).

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeGet Started with MATLAB についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by