Comment #0 by dlang-bugzilla — 2007-10-07T16:32:18Z
=== loader.d ===
import std.stdio;
import std.string;
import std.c.windows.windows;
void main()
{
writefln("Loading DLL...");
HANDLE h = LoadLibraryA("library.dll");
if(!h)
return writefln("Failed to load DLL.");
writefln("DLL loaded. Unloading...");
if(!FreeLibrary(h))
return writefln("Failed to unload DLL.");
writefln("DLL unloaded.");
}
=== library.d ===
(standard DLL template copied from the documentation)
import std.c.windows.windows;
HINSTANCE g_hInst;
extern (C)
{
void gc_init();
void gc_term();
void _minit();
void _moduleCtor();
void _moduleUnitTests();
}
extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
gc_init(); // initialize GC
_minit(); // initialize module list
_moduleCtor(); // run module constructors
_moduleUnitTests(); // run module unit tests
break;
case DLL_PROCESS_DETACH:
gc_term(); // shut down GC
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
// Multiple threads not supported yet
return false;
}
g_hInst=hInstance;
return true;
}
=== output ===
Loading DLL...
DLL loaded. Unloading...
=== comments ===
D's runtime (DMC libc) closes the standard streams when the DLL is unloaded. Call stack:
DllEntryPoint
__cexit
_exit
___fcloseall
_fclose
_close
Needless to say, that shouldn't happen with DLLs.
Workaround: import std.stdio and add
_fcloseallp = null;
somewhere in your DllMain.
Comment #1 by dlang-bugzilla — 2007-10-07T17:04:17Z
I just noticed that this is somewhat documented at http://digitalmars.com/d/dll.html#Dcode .
However, this applies not only when a program in D is the one loading the DLL. Thus, it should be moved outside the "D code calling D code in DLLs" section, and also into the "DLLs with a C Interface" source code template.
Comment #2 by r.sagitario — 2010-04-07T11:20:55Z
The workaround (setting _fcloseallp = null) also prevents any other open file from being closed.
I think it should be fixed in the C-runtime library, where the handle for stdin/out/err is taken from a call to GetStdHandle(), and probably should not be closed when terminating.
Comment #3 by zan77137 — 2010-10-06T05:50:52Z
*** Issue 4996 has been marked as a duplicate of this issue. ***
Comment #4 by dlang-bugzilla — 2014-02-12T19:34:19Z
Doesn't happen in D2.
Comment #5 by r.sagitario — 2017-04-14T15:16:05Z
Still happens with the example dclient/dserver in dmd/samples.
Comment #6 by razvan.nitu1305 — 2019-10-24T09:31:01Z
Comment #8 by razvan.nitu1305 — 2019-10-25T10:05:09Z
(In reply to Rainer Schuetze from comment #7)
> The pull request for the dmc runtime has been merged
> https://github.com/DigitalMars/dmc/pull/3 , but there has never been an
> update to the released snn.lib AFAICT.
Any ideas on what actions should be taken to update the snn.lib? This is the first time I hear about this.
Comment #9 by r.sagitario — 2019-10-25T10:33:03Z
(In reply to RazvanN from comment #8)
> Any ideas on what actions should be taken to update the snn.lib? This is the
> first time I hear about this.
Walter has to build it and upload it to http://ftp.digitalmars.com/snn.lib
That's where the release build program downloads it from.
Comment #10 by r.sagitario — 2019-10-28T08:24:21Z
I verified the reported example (after some updates) works with the new snn.lib in 2.089-rc1 (and still failed with 2.088.1).