What is a correct way to convert Julia-String UTF8 to byte array which can be exported as C-like string char*
using ccall callback function ?
pseudo-code:
jString = String("a_šČô_φ_привет_일_迪弗尺")
strByteArray = toByteArray(jString)
len = length(strByteArray)
# fnc is pointer to C callback function void(__stdcall*)(const char* str, const size_t len);
fnc != Ptr{Void}(0) && ccall(fnc, Void, (Cstring, Int64), strByteArray, len)
You can get the UTF8 bytes as an array with convert(Vector{UInt8}, jString)
but I guess you still need to append a zero byte for C compatibility.
No need to call something like toByteArray
, just pass the string to ccall
, which will handle everything automatically. The only thing you need to figure out is the length of the string in bytes, which can be obtained using sizeof
. Note that since you pass the length as an argument, you can use Ptr{UInt8}
instead of Cstring
to avoid checking for the presence of null bytes in the string. See the manual for details.
This would probably deserve a short mention in the manual. You could open an issue about that.
1 Like
thaks for hints. the resulting implementation:
Julia side
jString = String("a_šČô_φ_привет_일_迪弗尺")
fnc != C_NULL &&
ccall(fnc, Void, (Ptr{UInt8}, Cint), jString, sizeof(jString)) # @nalimilan nalimilan
CPP side: possible implementation - write data as arrived…
void callbackfn(const char* data, const int len )
{
std::ofstream ofs("myFile.txt", std::ios::binary);
ofs.write(data, len); // don't worry about null-terminated string
ofs.close();
}
Cool. Note you don’t even need to call String
. Also, more importantly, use Cint
instead of Int64
if you define len
as int
in the C code.
1 Like
I’ve corrected the Cint
as well ac C_NULL
in solution the code above.