On Friday, 31 August 2018 at 17:50:17 UTC, Steven Schveighoffer wrote:
What the C compiler is doing is storing it as data, and then storing the symbol to point at the first element in the data.

When you use const char* in D, it's expecting a *pointer* to be stored at that address, not the data itself. So using it means segfault. The static array is the correct translation, even though it leaks implementation details.

In C, it's working because C has the notion of a symbol being where an array starts. D has no concept of a C array like that, every array must have a length. So there is no equivalent you can use in D -- you have to supply the length.


NKML also wrote:
You need to declare your extern array as array in D and also in C, so that the compiler would know what that is (an array, not a pointer). In many situations C compiler would silently convert an array into a pointer (when it already knows its dealing with array), but it won't convert a pointer into an array.

Thank you Steve and NKML for your very clear and concise answers. This makes perfect sense.

I would like not to write as a static array in D because I cannot guarantee future version of the library to which I am linking would not change the length of the data. Steve's trick, below, looks like the ticket.


Alternatively, you can treat it as a const char:

extern(C) extern const(char) seq_nt16_str;

void main()
{
   import core.stdc.stdio;
   printf("%s\n", &seq_nt16_str); // should print the string
}

You could wrap it like this:

pragma(mangle, "seq_nt16_str");
private extern(C) extern const(char) _seq_nt16_str_STORAGE;

@property const(char)* seq_nt16_str()
{
   return &_seq_nt16_str_STORAGE;
}

To make the code look similar.

-Steve

That is a great trick, and I will use it.



Reply via email to