2

Reading Basic use of Pointers indicates that when a NativeCall C function returns pointer to an object with a class with repr('CPointer'), it will call submethod DESTROY where I can put my function to free the C memory. (This is fantastic and an amazing capability, btw.)

What if I get back a generic Pointer, but later decide to nativecast() it to the class? Will that also correctly DESTROY() it when garbage collected? I think (and hope) it will, but haven't been able to prove that to myself.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Curt Tilmes
  • 3,035
  • 1
  • 12
  • 24

1 Answers1

3

I strongly suspect it will, given the behaviour of the following test case:

use NativeCall;

my $done = False;

class Foo is repr<CPointer> {
    method id { nativecast(Pointer[int32], self).deref }

    # only log destrution of first object
    submethod DESTROY {
        if !$done {
            $done = True;
            say "first Foo with id {self.id} has died";
        }
    }
}

# avoid premature collection of buffers
my @keep-alive;

# allocate a bunch of buffers and cast them to Foo
# keep going until the garbage collector gets triggered
my $ = nativecast(Foo, @keep-alive.push(buf32.new($++)).tail)
    while !$done;

The destructor will be called when a Foo gets reclaimed, even if said Foo was created via a nativecast. If you want, you may add an explicit conversion to Pointer inbetween, but that shouldn't and doesn't make any difference.

Christoph
  • 164,997
  • 36
  • 182
  • 240