D string to C struct fixed-size array
Jack
jckj33 at gmail.com
Mon Jan 4 16:35:23 UTC 2021
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);
More information about the Digitalmars-d-learn
mailing list