Thread overview
Linux shared library loading/linking from C does not invoke (shared) static this
Jan 12, 2021
ichneumwn
Jan 12, 2021
Imperatorn
Jan 12, 2021
ichneumwn
Jan 12, 2021
ichneumwn
Jan 12, 2021
Mike Parker
Jan 12, 2021
ichneumwn
January 12, 2021
Dear all,

I was trying to invoke some D code from Python and ran into issues which I eventually traced back to a simple example on the D website itself :

https://dlang.org/articles/dll-linux.html

Particularly the section "Dynamically Loading a D DLL From a C Program"

In my case, and indeed already in 2013 (https://forum.dlang.org/post/yeqyqaaguhngczlnvqnq@forum.dlang.org), shared static this does not get invoked

I normally use:
LDC - the LLVM D compiler (1.21.0):
  based on DMD v2.091.1 and LLVM 10.0.0   (under Linux)

but I also tried
DMD64 D Compiler v2.095.0

Is the solution suggested in the linked post the "canonical way"?

Where could one file a suggestion for an update to the documentation?

Cheers!

PS Enjoying my project in D especially how easy it is to get the same code to run under windows too




January 12, 2021
On Tuesday, 12 January 2021 at 08:19:45 UTC, ichneumwn wrote:
> Where could one file a suggestion for an update to the documentation?

In the top right section of the page you can click the "Improve this page"-link.

January 12, 2021
On Tuesday, 12 January 2021 at 08:19:45 UTC, ichneumwn wrote:
> Dear all,
>
> I was trying to invoke some D code from Python and ran into issues which I eventually traced back to a simple example on the D website itself :
>
> https://dlang.org/articles/dll-linux.html
>
> Particularly the section "Dynamically Loading a D DLL From a C Program"
>
> In my case, and indeed already in 2013 (https://forum.dlang.org/post/yeqyqaaguhngczlnvqnq@forum.dlang.org), shared static this does not get invoked
>
> I normally use:
> LDC - the LLVM D compiler (1.21.0):
>   based on DMD v2.091.1 and LLVM 10.0.0   (under Linux)
>
> but I also tried
> DMD64 D Compiler v2.095.0
>
> Is the solution suggested in the linked post the "canonical way"?
>
> Where could one file a suggestion for an update to the documentation?
>
> Cheers!
>
> PS Enjoying my project in D especially how easy it is to get the same code to run under windows too

Follow on to my own question: on Linux, with gcc, I have created the following file "starter.c" that I inject into my D shared library:

  int rt_init(void);
  int rt_term(void);

  // should really check for errors!
  static void __attribute__((constructor)) Dstarter(void) {
    rt_init();
  }

  static void __attribute__((destructor)) Dterminator(void) {
    rt_term();
  }

That seems to do the trick. Not sure how clean this is?



January 12, 2021
On Tuesday, 12 January 2021 at 09:31:08 UTC, ichneumwn wrote:

>
> Follow on to my own question: on Linux, with gcc, I have created the following file "starter.c" that I inject into my D shared library:
>
>   int rt_init(void);
>   int rt_term(void);
>
>   // should really check for errors!
>   static void __attribute__((constructor)) Dstarter(void) {
>     rt_init();
>   }
>
>   static void __attribute__((destructor)) Dterminator(void) {
>     rt_term();
>   }
>
> That seems to do the trick. Not sure how clean this is?

You should be able to do the same in D with `pragma(crt_constructor)` and `pragma(crt_destructor)`:

https://dlang.org/spec/pragma.html#crtctor
https://dlang.org/spec/pragma.html#crtdtor
https://dlang.org/changelog/2.078.0.html#crt-constructor


January 12, 2021
On Tuesday, 12 January 2021 at 09:49:46 UTC, Mike Parker wrote:
> On Tuesday, 12 January 2021 at 09:31:08 UTC, ichneumwn wrote:
>
>>
>> Follow on to my own question: on Linux, with gcc, I have created the following file "starter.c" that I inject into my D shared library:
>>
>>   int rt_init(void);
>>   int rt_term(void);
>>
>>   // should really check for errors!
>>   static void __attribute__((constructor)) Dstarter(void) {
>>     rt_init();
>>   }
>>
>>   static void __attribute__((destructor)) Dterminator(void) {
>>     rt_term();
>>   }
>>
>> That seems to do the trick. Not sure how clean this is?
>
> You should be able to do the same in D with `pragma(crt_constructor)` and `pragma(crt_destructor)`:
>
> https://dlang.org/spec/pragma.html#crtctor
> https://dlang.org/spec/pragma.html#crtdtor
> https://dlang.org/changelog/2.078.0.html#crt-constructor

Perfect, thanks! Interestingly, as I removed the C stub and tried the D route, I noticed that just calling rt_init() is enough to also get static ~this() to run on exit. In fact then adding writeln in a pragma(crt_destructor) function shows that it gets called after static ~this().

For anyone stumbling across this thread and looking for the import for rt_init/term:

import core.runtime : rt_init, rt_term;

January 12, 2021
On Tuesday, 12 January 2021 at 09:02:38 UTC, Imperatorn wrote:
> On Tuesday, 12 January 2021 at 08:19:45 UTC, ichneumwn wrote:
>> Where could one file a suggestion for an update to the documentation?
>
> In the top right section of the page you can click the "Improve this page"-link.

Thanks, I will leave it though. I do not want to mess about and write about something I have just learnt in the last hour. That could do more damage than good.