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.