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