Clear Filters
Clear Filters

Calling functions in a C library results in a crash when passing long strings

5 views (last 30 days)
I am developing a Matlab interface for an external C library. The library handles all string outputs with the following utility function:
size_t copyString(const std::string& source, char* dest, size_t length)
{
const char* c_src = source.c_str();
size_t N = std::min(length, source.length()+1);
size_t ret = (length >= source.length() + 1) ? 0 : source.length() + 1;
std::copy(c_src, c_src + N, dest);
if (length != 0) {
dest[length-1] = '\0';
}
return ret;
}
copyString outputs the length of the source string if an empty string is passed as input. Then the user would create a buffer that matches the length of the source string, then the function copies the characters in the source string into the destination string.
Here is an example that uses such utility function:
int thermo_getEosType(int n, size_t leneos, char* eos)
{
try {
return static_cast<int>(copyString(ThermoCabinet::item(n).type(), eos, leneos));
} catch (...) {
return handleAllExceptions(-1, ERR);
}
}
In Matlab, I then call thermo_getEosType using the following code:
buflen = calllib(ct, 'thermo_getEosType', tp.tpID, 0, ''); % determine the length of buffer
if buflen > 0
aa = char([zeros(1, buflen, 'int8')]); % create an empty buffer string with length buflen
ptr = libpointer('cstring', aa); % create a cstring pointer to the buffer
[~, bb] = calllib(ct, 'thermo_getEosType', ...
tp.tpID, buflen, ptr); % copy values of the source string into the buffer
e = bb;
clear aa bb ptr;
end
Here's the function signature for thermo_getEosType:
[int32, cstring] thermo_getEosType(int32, uint64, cstring)
This code works fine when the length of the string is small (buflen < 10). But when the string is long (buflen > 100), Matlab crahes when copying the string to the buffer. I use libpointer instead of automatic conversion according to the following recommendation in Matlab documentations:
Often, you can simply pass a MATLAB variable (passing an argument by value), even when the signature for that function declares the argument to be a pointer. There are times, however, when it is useful to pass a lib.pointer.
  • You want to modify the data in the input arguments.
  • You are passing large amounts of data, and you want to control when MATLAB makes copies of the data.
  • The library stores and uses the pointer so you want the MATLAB function to control the lifetime of the lib.pointer object.
The older version of the interfaces uses MEX functions but the goal of my development is eliminating the MEX interface. Here is how the MEX function calls thermo_getEosType:
iok = -1;
int buflen;
char* output_buf;
buflen = thermo_getEosType(ph, 0, 0);
if (buflen > 0) {
output_buf = (char*)mxCalloc(buflen, sizeof(char));
iok = thermo_getEosType(ph, buflen, output_buf);
}
if (iok == 0) {
plhs[0] = mxCreateString(output_buf);
return;
} else {
reportError();
I am not sure why the older MEX function is perfectly stable while the direct calling method crashes. I appreciate any help!

Answers (1)

Himanshu
Himanshu on 28 Dec 2023
Hello,
I understand that you are trying to interface MATLAB with an external C library and are encountering crashes when copying long strings from C to MATLAB. The error likely occurs due to how memory is allocated and managed between the two environments.
To resolve the issue, please follow the below steps:
  1. Analyze the memory management in the MEX interface and the direct calling method.
  2. Ensure that proper memory allocation is done in MATLAB to avoid buffer overflows. Pre-allocate the buffer in MATLAB with the correct size and data type.
  3. Verify that the C function "copyString" works correctly with large strings outside of MATLAB.
  4. Ensure that the buffer length "leneos" accounts for the null terminator in C strings when passed to "thermo_getEosType".
  5. Use "libpointer" to create a pointer to the pre-allocated buffer. Pass the "libpointer" to the C function and check the return value to ensure the operation was successful. Clear the "libpointer" after retrieving the data to avoid memory leaks.
Please refer to the below documentation to understand more about "libpointer" in MATLAB.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!