Temporarily protect array from garbage collection

2014-04-24 Thread Lars T. Kyllingstad via Digitalmars-d-learn
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


Re: Temporarily protect array from garbage collection

2014-04-24 Thread Lars T. Kyllingstad via Digitalmars-d-learn

On Thursday, 24 April 2014 at 20:09:38 UTC, Justin Whear wrote:
You can use GC.addRoot() from core.memory before passing the 
pointer to

the C function, then use GC.removeRoot in your myFree function.


Perfect, thanks!


Struct size

2014-04-19 Thread Lars T. Kyllingstad via Digitalmars-d-learn

Say I have two structs, defined like this:

struct A { /* could contain whatever */ }

struct B { A a; }

My question is, is it now guaranteed that A.sizeof==B.sizeof, 
regardless of how A is defined (member variable types, alignment, 
etc.)?  More to the point, say I have a function foo() which 
looks like this:


extern(C) void foo(A* ptr, size_t len);

Is it now guaranteed that I can safely pass it a pointer to an 
array of Bs?  That is,


auto arr = new B[10];
foo(cast(A*) arr.ptr, arr.length);

Thanks,
Lars


Re: Struct size

2014-04-19 Thread Lars T. Kyllingstad via Digitalmars-d-learn
On Saturday, 19 April 2014 at 12:26:16 UTC, Andrej Mitrovic via 
Digitalmars-d-learn wrote:

On 4/19/14, Lars T. Kyllingstad via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

Say I have two structs, defined like this:

 struct A { /* could contain whatever */ }

 struct B { A a; }

My question is, is it now guaranteed that A.sizeof==B.sizeof?


The best thing to do is add a static assert and then you can 
relax:


That's what I've done, but it would be nice to know the code 
won't break due to some combination of platform and/or compiler 
switches I didn't think to test.  Anyway, I've played around a 
bit, and found that a combination of struct and field alignment 
*can* break my assumption:


align(1) struct A
{
char c;
align(1) int i;
}

struct B { A a; }

Now, A.sizeof is 5, while B.sizeof is 8.  I'd have to add 
align(1) to the declaration of B to fix it.