Thread overview
DMD dll GC bug when calling a function from an interface that creates a new object
Oct 27, 2022
Hipreme
Nov 03, 2022
cc
Nov 03, 2022
Adam D Ruppe
Nov 03, 2022
cc
Nov 03, 2022
Guillaume Piolat
Nov 03, 2022
Imperatorn
October 27, 2022

I have some sample code:

interface IFont
{
  IFont createFontWithSize(int size);
}

Main Code:

import common;
class TTFFont : IFont
{
  IFont createFontWithSize(int size){return new TTFFont;}
}

export extern(System) IFont newFont()
{
  auto ret = new TTFFont();
  GC.addRoot(ret);
  return ret;
}

DLL Code:

import common;

Runtime.initialize();
IFont function() newFont;
newFont = loadSymbol("newFont");
IFont myFont = newFont();
IFont otherFont = myFont.createFontWithSize(32); //Gets collected after some time

For it not get collected after some time, I actually need to put GC.addRoot inside the function createFontWithSize. This makes it literally unusable

November 03, 2022

On Thursday, 27 October 2022 at 02:42:47 UTC, Hipreme wrote:

>

For it not get collected after some time, I actually need to put GC.addRoot inside the function createFontWithSize. This makes it literally unusable

D DLLs each operate under a separate GC context from the main process, so anything newed in a DLL may be collected if a reference to it isn't maintained there. You can link them together so they share the same GC with something like this:

// mydll.d
extern(C) {
	void gc_setProxy(void* p);
	void gc_clrProxy();
}
export void MyDLL_Initialize(void* gc) {
	gc_setProxy(gc);
}
export void MyDLL_Terminate() {
	gc_clrProxy();
}


// main.d
extern (C) {
	void* gc_getProxy();
}
void main() {
	MyDLL_Initialize(gc_getProxy()); // Share this process's GC with the DLL
	scope(exit) MyDLL_Terminate();
	/* do stuff */
}

Source: http://arsdnet.net/dlang.org/dll.html

November 03, 2022
On Thursday, 3 November 2022 at 04:38:28 UTC, cc wrote:
> D DLLs each operate under a separate GC context from the main process, so anything `new`ed in a DLL may be collected if a reference to it isn't maintained there.  You can link them together so they share the same GC with something like this:

This is only true on dmd windows (with ldc, you get a shared druntime to all mixed) and you don't have to set the proxy yourself - Runtime.loadLibrary does it for you.

But do make sure you are using Runtime.loadLibrary! SimpleDllMain alone i don't think does it.... so this might be hipreme's problem.

> Source: http://arsdnet.net/dlang.org/dll.html

This is an old copy of the website newer info on the d wiki.
November 03, 2022

On Thursday, 3 November 2022 at 04:38:28 UTC, cc wrote:

>

D DLLs each operate under a separate GC context from the main process, so anything newed in a DLL may be collected if a reference to it isn't maintained there. You can link them together so they share the same GC with something like this:

Ooooooh this explain so much strange bugs we had with D programs hosting D DLL.

November 03, 2022

On Thursday, 3 November 2022 at 14:53:19 UTC, Guillaume Piolat wrote:

>

On Thursday, 3 November 2022 at 04:38:28 UTC, cc wrote:

>

D DLLs each operate under a separate GC context from the main process, so anything newed in a DLL may be collected if a reference to it isn't maintained there. You can link them together so they share the same GC with something like this:

Ooooooh this explain so much strange bugs we had with D programs hosting D DLL.

Are you on the D Discord btw?

November 03, 2022

On Thursday, 3 November 2022 at 12:33:17 UTC, Adam D Ruppe wrote:

>

This is only true on dmd windows (with ldc, you get a shared druntime to all mixed)

Ah, that's another confusing difference to have to remember. Does the wiki have an up to date list of known compiler differences? Searching for this usually gets me 11-year old stackoverflow threads.