On 12/31/2014 8:19 PM, Laeeth Isharc wrote:
Argh - no way to edit.

What's best practice here?

D strings are not null-terminated.
===
cpling.c

char* cpling(char *s)
{
   s[0]='!';
   return s;
}
===
dcaller.d

extern(C) char* cpling(char* s);

void callC()
{
   writefln("%s",fromStringz(cpling("hello\0")));
}

or

void callC()
{
   writefln("%s",fromStringz(cpling(toStringz("hello"))));
}

===

am I missing a better way to do this?

String literals are always null-terminated. You can typically pass them as-is and D will do the right thing (you can also pass "MyStr".ptr if you want). Use toStringz when the string came from an external source (read from a file, passed into a function and so on), since you can't be sure if it was a literal or not. toStringz will recognize if it has a null-terminator and will not do anything if it does.

Also, you should make sure to consider std.conv.to on any C strings returned into D if you are going to keep them around. fromStringz only creates a slice, which is fine for how you use it here, but could get you into trouble if you aren't careful. std.conv.to will allocate a new string.

Reply via email to