Passing string literals to C
Mike Parker via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Dec 31 03:45:36 PST 2014
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.
More information about the Digitalmars-d-learn
mailing list