On Wednesday, 15 August 2018 at 02:40:22 UTC, Joe wrote:


I understand that, Mike. However if I'm not mistaken given something in C like

char* strs[] = { "This", "is a", "test"};

AFAIK, even with -betterC and an extern (C), the literals will still be understood by D as type "string", and there is no other way around it, right?

I could put the array and the function in its own C file for the time being, but instead chose to replace the toStringz by a small hack: use memcpy to copy the string to a stack fixed, big enough array and a NUL terminator.

String literals are implicitly convertible to const(char)* and are guaranteed to be nul-terminated like a C string, so this works:

import core.stdc.stdio;
extern(C) void main()
{
    const(char)* foo = "foo";
    puts(foo);
}
https://run.dlang.io/is/FZSXc3

For plain char*, a simple cast works:

char* foo = cast(char*)"foo";

The problem is with the array initializer, as the C-style {x, y, z} only works on structs in D, and D's [x, y, z] requires TypeInfo, which isn't available in -betterC, a problem you run into even when your array is string[].

However, the initializer works fine with static arrays in -betterC, so this works:

import core.stdc.stdio;
extern(C):

void some_c_func(const char** strs, size_t numStrs) {
    for(size_t i=0; i<numStrs; ++i) {
        puts(strs[i]);
    }
}

void main()
{
    const(char)*[3] strs = ["one", "two", "three"];
    some_c_func(strs.ptr, strs.length);
}

https://run.dlang.io/is/pxmGyh

Does that help?

Reply via email to