On Sunday, 3 January 2021 at 08:43:34 UTC, bdh wrote:
Hi,
I'm trying to create bindings to the GraphcicsMagick C library
which has the following struct defined:
[...]
Do you mean fill .filename member from a D string? something like
this?
import std.stdio;
[...]
struct Image
{
/* other members skipped */
char[MaxTextExtent] filename;
}
}
[...]
import std.stdio;
extern(C)
{
enum MaxTextExtent = 2053;
struct Image
{
/* other members skipped */
char[MaxTextExtent] filename;
}
}
void main()
{
import std.string : toStringz;
import core.stdc.string : memcpy, strlen;
auto i = Image();
auto dstr = "hello world!!!"; // D string
auto cs = toStringz(dstr); // now it's C-null-terminatted
string
// since .filename isn't a pointer but an array, I think
// you have to use memcpy() here. = operator wouldn't work
properly.
memcpy(&i.filename[0], &cs[0], strlen(cs)+1);
// casting away arrayness to make it a pointer (that a C's
array is after all)
printf("str = [%s]\n", &i.filename[0]);
}
[...]
note that even if .filename was a pointer, in order to the C
converted stirng don't turn into garbage in a GC cycle, you would
have to either keep reference to dstr around or malloc() and
memcpy() it. So you need to convert from C to D: you can use
fromStringz() on D string then to!string to convert to a D
string, like this:
import std.conv : to;
import std.string : fromStrinz;
string s = to!string(cstr.fromStringz);