In D.learn in a short thread with Lars T. Kyllingstad we have discussed about 
possible bugs coming from using C code through D and forgetting to 
zero-terminate strings given to C libs.

You can use the D type system (originally I have used a typedef) to be sure you 
have applied toStringz() on D strings. This is just a starting point, probably 
it can be improved in several ways:


import std.string: toStringz;

struct Cstring {
    const(char)* ptr; // const(ubyte)* ?
    static Cstring opCall(string s) {
        Cstring cs;
        cs.ptr = toStringz(s);
        return cs;
    }
}

extern(C) Cstring strcmp(Cstring s1, Cstring s2);

void main() {
    auto s1 = "abba";
    auto s2 = "red";
    auto r2 = strcmp(Cstring(s1), Cstring(s2));
}

Maybe it's better if toStringz() (and ptr inside Cstring) to return a ubyte* 
because C char/unsigned char can be an unvalid UFT8.

You have to remember to use Cstring (instead of ubyte or char) everywhere in 
the extern(C) line, but this is done only once for a function in a module, 
while the calls to the C function can be many, so I think it's an improvement.

Once improved this may be even considered for std.string.

Bye,
bearophile

Reply via email to