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