www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - D DLL crashes if not run on the main thread

reply raven09 <dsaqwertyqh jehg.com> writes:
Hi,

winforms app using P/Invoke. Everything works wonderfully as long 
as it is called from the main thread (at least I assume that it 
not being on the main thread is causing the issues). If I start a 
new thread and try using any function imported from the DLL the 
program will instantly crash. Debugging the winforms app with VS 
shows that it does indeed crash on that function call, but does 
not provide any more information. Further testing I did was 
writing a test DLL that basically just contained `` extern(C) 

program: it worked fine until I put it in a separate thread.

I *assume* that this has something to do with D's GC? But I tried 
calling GC.disable() and nothing changed. Any help or insight 
would be appreciated.
Thanks in advance
Sep 05 2023
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
Whatever is going on, that function you showed would not call into 
druntime. So I don't think it's related.

As of right now I have no tips as I'm tired, but I suspect its on the 
.net end.
Sep 05 2023
parent reply raven09 <dsaqwertyqh jehg.com> writes:
On Tuesday, 5 September 2023 at 22:53:35 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 Whatever is going on, that function you showed would not call 
 into druntime. So I don't think it's related.

 As of right now I have no tips as I'm tired, but I suspect its 
 on the .net end.
Sorry for the confusion, that function actually runs fine and it was something completely unrelated that caused the crash. However, swapping that out for a function that does interact with the druntime does cause a crash (it calls a function template inside of a class and returns the value)
Sep 05 2023
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
Assuming it works outside of a DLL, you're probably missing the runtime 
initialization calls.

Mix SimpleDllMain in (or do your own). 
https://github.com/dlang/dmd/blob/9639d72ea0883808feff7aba71d87c5a78fb7f92/druntime/src/core/sys/windows/dll.d#L577
Sep 05 2023
prev sibling next sibling parent Hipreme <msnmancini hotmail.com> writes:
On Tuesday, 5 September 2023 at 22:45:28 UTC, raven09 wrote:
 Hi,

 winforms app using P/Invoke. Everything works wonderfully as 
 long as it is called from the main thread (at least I assume 
 that it not being on the main thread is causing the issues). If 
 I start a new thread and try using any function imported from 
 the DLL the program will instantly crash. Debugging the 
 winforms app with VS shows that it does indeed crash on that 
 function call, but does not provide any more information. 
 Further testing I did was writing a test DLL that basically 
 just contained `` extern(C) export int TestMe() { return 5; }`` 

 it in a separate thread.

 [...]
Hi, maybe you could try putting your DLL load function inside the thread which you're calling your function? Maybe there could be something related to that.
Sep 05 2023
prev sibling parent Guillaume Piolat <first.name gmail.com> writes:
On Tuesday, 5 September 2023 at 22:45:28 UTC, raven09 wrote:
 I *assume* that this has something to do with D's GC? But I 
 tried calling GC.disable() and nothing changed. Any help or 
 insight would be appreciated.
 Thanks in advance
If you want to have a D DLL called from elsewhere, and don't control which threads call your dynlib: - first thread that comes (or the DLL load itself) should initialize the runtime. You can use pragma(crt_destructor) to deinitialize the D runtime. - threads that come through a callback should in general register to the D runtime, and unregister on exit. They will not hold roots while they are back in C land, and you must unregister them on exit else the GC will try to pause possibly dead threads when it collects. You can leave some threads unregistered, but then I'm not sure for TLS and they certainly cannot hold GC roots. You can also leave the whole D runtime disabled, but that is annoying (no GC, amongst other things).
Sep 05 2023