how to handle memory ownership when interfacing with C/C++ via internal pointers

timotheecour timothee.cour2 at gmail.com
Tue Oct 15 14:41:32 PDT 2013


On Thursday, 10 October 2013 at 23:02:29 UTC, Timothee Cour wrote:
> Short version:
> I have a struct A* aptr allocated in C/C++ with an internal
> pointer aptr->ptr (say a double*)
> I want to store a reference x (say double[]) in D to aptr only 
> through
> aptr->ptr, not through aptr directly as it's inconvenient in my 
> use case.
>
> How do I achieve that, so that when x goes out of scope, some 
> deallocator
> for aptr will be called ?
>
> Long version:
> ----
> suppose I have C++ code:
> struct A{
>   double*ptr;
>   A(size_t n){ptr=(double*)malloc(n);}
>   ~A(){free(ptr);}
> };
>
> and a D wrapper around it:
> extern(C){struct A; A*A_new(size_t n); void A_delete(A*a);
> double*A_ptr(A*a);}
>
> I want to use it as follows:
>
> double[] get_x(size_t n){
>  return A_new(n).A_ptr[0..n];
> }
>
> void main(){
>   double[]x=get_x(n);
> // do something with x;
> }
> ----
>
> It's trivial to handle this via a class wrapper:
> class A2{
> A*a;
> this(size_t n){a=A_new(n);}
> ~this(){A_delete(n);}
> double*ptr(){return A_ptr(a);}
> }
> double[] get_x(size_t n){
>  auto a2=new A2(n);
>  return a2.ptr;
> //this doesn't help much though, A2 will go out of scope when 
> this function
> exits.
> }
>
>
> but I don't want to maintain objects of class A2 around, just 
> double[]
> slices as above.
>
> Is there some magic involving core.memory.addRoot,addRange 
> (etc) I can use
> so that a2 stays alive as long as x stays alive? (in which case 
> when x goes
> out of scope, 'a2' will too, and will call A_delete).
>
> Thanks

Ping?
Is anything above unclear?

here are more details (in a simplified setting):

say, I have an image class D_image which has fields:
ubyte* ptr //pointer to memory
uint[2] size;

I'd like to interface with, say, a swig-wrapped opencv C++ image 
class Swig_image, so that when an object d_image:D_image goes out 
of scope (and its pointer ptr also goes out of scope), (with 
d_image constructed from an object swig_image of type 
Swig_image), then swig_image will also go out of scope.

again, this can be done by adding a field to D_image (say of type 
void* to make it work with any source), buy I'm wondering whether 
this can be achieved without adding this field, with some GC 
magic associating a pointer (ptr) to another pointer (cast(void*) 
swig_image).

This would make interfacing with C++ libs much easier as there 
would be no bookkeeping in user code.








More information about the Digitalmars-d-learn mailing list