extern __gshared const(char)* symbol fails
James Blachly
james.blachly at gmail.com
Fri Aug 31 19:05:11 UTC 2018
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.
More information about the Digitalmars-d-learn
mailing list