Request assistance initializing struct instance at global scope
Andrew Edwards
edwards.ac at gmail.com
Tue Dec 8 02:45:09 UTC 2020
On 12/7/20 10:56 PM, Adam D. Ruppe wrote:
> On Monday, 7 December 2020 at 04:13:16 UTC, Andrew Edwards wrote:
>> Given:
>>
>> ===============
>> extern(C):
>> char*[] hldr;
>
> Why is this extern(C)? A D array ere is probably wrong.
To stay as close to the original implementation as possible. This will
all change when the entire code base compiles in D.
> In C, a `char*[] hldr = {...}` is actually represented in D as a static
> length array, like `char*[1] = [null];`
Thanks. Because I was having issues I didn't know how to resolve, I
actually defined it as `string ft` instead and passed around `ft.ptr`
when calling
> It should also generally be __gshared if it was declared in C (C
> defaults to global, D defaults to thread-local), and if declared in C,
> an additional extern may be required.
>
Noted. I'll keep that in mind when trying to link to C in the future.
>
> So, if you are trying to *link* to C code that has this:
>
I'm porting it. All of the code is available from the D source file.
>
> You'd bind to it in D with
>
> ---
> // D
> extern(C) extern __gshared char*[1] hldr; // matches the C. Make sure
> the length matches too
Ok, got it.
> S[] s = [S(cast(char*) "c", &hldr[0])]; // that cast is super iffy
> though. Should S have `const(char)* ft` instead?
>
Probably. I just did a direct port. They had char* so I just kept it
that way. I'll change it to string once the initial port is complete.
But I'll remember that when I come across it in the future.
>
> In that thing:
>
> extern(C) - tells it it has a C name.
> extern - tells it the actual variable is declared externally. This
> second one makes the linker pull the variable's address from the C code
> instead of declaring a new variable in D that can be used from C.
> __gshared - turn off D's thread local default to match C's global.
>
Learning has occurred. Thanks.
>
> Now if you are translating C code to D, that might be different,
> certainly the second extern is wrong then, and you need to copy over the
> initial value but the rest still works:
This.
> ```
> // no more second extern, D is now creating a new variable, then it
> needs to know the value too
> extern(C) __gshared char*[1] hldr = [null];
Okay. I'll need to be mindful of this in the future. But to resolve the
issue this time around, I just used a string[] since that's the end
state anyway.
> // rest is the same
> // including
> S[] s = [S(cast(char*) "c", &hldr[0])]; // since it is a gshared static
> array, this still works
> ```
Yup... got this to compile with main() and static this() in the correct
location.
>
> But there's a few other contexts that might change this, then you
> probably do want the static constructor, or maybe you can make some
> things immutable and make it work that way. All depends on a bit more
> information than your code gives on its own....
Thanks for the lesson... I've learned quite a lot.
More information about the Digitalmars-d-learn
mailing list