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.