Thread overview
How to call 'shared static this()' code of a D shared library?
Jan 18, 2020
Ali Çehreli
Jan 18, 2020
Adam D. Ruppe
Jan 18, 2020
Guillaume Piolat
Jan 18, 2020
Ali Çehreli
Jan 20, 2020
Ali Çehreli
Jan 18, 2020
Adam D. Ruppe
January 17, 2020
Simply linking my D shared library with foreign code (Python with the help of ctypes in this case) does not work. What function should I call? What about 'shared static ~this()'? And would the answer be different for 'static this()' etc.?

Thank you,
Ali
January 18, 2020
Did you already try rt_init? That should trigger it....
January 18, 2020
On Saturday, 18 January 2020 at 03:53:43 UTC, Adam D. Ruppe wrote:
> Did you already try rt_init? That should trigger it....

Indeed, this is done by runtime initialization.
January 18, 2020
btw there is also a `pragma(crt_constructor)` thing you can put on individual functions for pure C runtime init things.
January 18, 2020
On 1/18/20 6:14 AM, Guillaume Piolat wrote:
> On Saturday, 18 January 2020 at 03:53:43 UTC, Adam D. Ruppe wrote:
>> Did you already try rt_init? That should trigger it....
> 
> Indeed, this is done by runtime initialization.

Thank you, Adam and Guillaume. That tells me I've been using druntime without initializing it. :D I'm guessing the problem would be the lack of garbage collection? Otherwise, dynamic arrays seemed to work correctly (so far).

Ali

Aside: A tip for others who may need to call the Python C API from D, you have to call PyGILState_Ensure() and PyGILState_Release(): https://docs.python.org/3/c-api/init.html#non-python-created-threads
January 19, 2020
On 1/17/20 7:53 PM, Adam D. Ruppe wrote:
> Did you already try rt_init? That should trigger it....

I was under the impression that the extern (C) function rt_init() would magically be exposed from the library but 'nm' showed no such symbol. So, I ended up exposing a my_init() function, which called rt_init() internally.

I've realized that rt_init() is sneaky: it returns 1 for success. WAT!? :p Then I discovered the more readable Runtime.initialize(), which is also sneaky by returning 'true' for success. WAT!? WAT!? :p

This worked:

import core.runtime;

extern (C)
int my_init() {
  return tried({
    return Runtime.initialize ? 0 : 1;
  });
}

my_deinit() is similar...

Ali

P.S.'tried' is a function template that I wrote, which catches all throwables, logs the issue, and returns 1 as an error code.