Temporarily protect array from garbage collection

Justin Whear via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Apr 24 13:09:38 PDT 2014


On Thu, 24 Apr 2014 19:55:37 +0000, Lars T. Kyllingstad wrote:

> Is it possible to temporarily prevent the garbage collector from
> collecting a memory block even if there are no references to it?
> 
> The use case is as follows:  I want to call a C library function which
> expects to take ownership of a buffer.  It looks something like this:
> 
>      alias FreeFunc = extern(C) void function(void*, void*)
> nothrow;
> 
>      extern(C) void foo(void* buf, size_t len,
>                         FreeFunc free, void* ctx) nothrow;
> 
> Here, 'buf' is a pointer to the buffer, 'len' is the length of the
> buffer, 'free' is a function to deallocate the buffer when the library
> is done with it, and 'ctx' is a user-supplied context pointer.  Upon
> deallocation, 'free' receives two parameters; the pointer to the buffer
> and the context pointer.  The latter can be anything, even null, as it
> is just passed to 'free' and not used for anything else.
> 
> Here is the problem:  I want to be able to use a garbage-collected
> dynamic array with this function, but I don't want to have to retain a
> reference to it in my program.  (I don't know when the C library will
> call the free function.)  In other words, I want something like this:
> 
>      extern(C) void myFree(void* ptr, void* ctx)
>      {
>          enableGCFor(ptr);
>      }
> 
>      auto arr = new int[123];
>      disableGCFor(arr);
>      foo(arr.ptr, arr.length, &myFree, null);
>      arr = null;
> 
> Is this at all possible?
> 
> Thanks,
> Lars

You can use GC.addRoot() from core.memory before passing the pointer to 
the C function, then use GC.removeRoot in your myFree function.


More information about the Digitalmars-d-learn mailing list