what's the right way to get char* from string?

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu May 5 06:36:50 PDT 2016


On 5/5/16 11:53 AM, pineapple wrote:
> On Thursday, 5 May 2016 at 07:49:46 UTC, aki wrote:
>> Hello,
>>
>> When I need to call C function, often need to
>> have char* pointer from string.
>
> This might help:
>
> import std.traits : isSomeString;
> import std.string : toStringz;
>
> extern (C) int strcmp(char* string1, char* string2);
>
> int strcmpD0(S)(in S lhs, in S rhs) if(is(S == string) || is(S ==
> const(char)[])) { // Best
>      return strcmp(
>          cast(char*) toStringz(lhs),
>          cast(char*) toStringz(rhs)
>      );
> }

This is likely a correct solution, because strcmp does not modify any 
data in the string itself.

Practically speaking, you can define strcmp as taking const(char)*. This 
is what druntime does: http://dlang.org/phobos/core_stdc_string.html#.strcmp

> int strcmpD1(S)(in S lhs, in S rhs) if(is(S == string) || is(S ==
> const(char)[])) { // Works
>      return strcmp(
>          cast(char*) lhs.ptr,
>          cast(char*) rhs.ptr
>      );
> }

Note, this only works if the strings are literals. Do not use this 
mechanism in general.

> /+
> int strcmpD2(S)(in S lhs, in S rhs) if(is(S == string) || is(S ==
> const(char)[])) { // Breaks
>      return strcmp(
>          toStringz(lhs),
>          toStringz(rhs)
>      );
> }
> +/

Given a possibility that you are calling a C function that may actually 
modify the data, there isn't a really good way to do this.

Only thing I can think of is.. um... horrible:

char *toCharz(string s)
{
    auto cstr = s.toStringz;
    return cstr[0 .. s.length + 1].dup.ptr;
}

-Steve


More information about the Digitalmars-d-learn mailing list