"Kent S." <happy / user.com> writes:

> You don't have to free memory yourself. With Ruby/DL you are dealing
> with DL::PtrData objects that basically represent a memory
> pointer. When there are no references to a PtrData object left, GC
> will collect this object and invoke its free routine, which takes
> care of the allocated memory. Take a look at PtrData#free
> attribute. BTW, if you know that your library function returns a
> pointer to some kind of static buffer and you don't want a PtrData
> object release this buffer, just set its free attribute to nil.

Okay, but it looks like by default PtrData#free is nil, right?  Do I
always have to specify a freeing function?

It seems as though the result of DL::malloc also does not have the
#free attribute set by default.

> irb(main):001:0> require 'dl/import'
> => true
> irb(main):002:0> module TestDLL
> irb(main):003:1>   extend DL::Importable
> irb(main):004:1>   dlload 'test.bundle'
> irb(main):005:1>   extern "int get_data(char**, int*)"
> irb(main):006:1> end
> => #<DL::Symbol:0x0x4c9910 func=0x0x1e6f28 'int get_data(void *, void *);'>
> irb(main):007:0> data = DL::PtrData.new(0)
> => #<DL::PtrData:0x0x4905f0 ptr=0x0x0 size=0 free=0x0x0>
> irb(main):008:0> data.free = DL::FREE
> => #<DL::Symbol:0x0x456120 func=0x0x5876ec 'void free(void *);'>
> irb(main):009:0> len = DL::PtrData.malloc(DL.sizeof('I'))
> => #<DL::PtrData:0x0x441f30 ptr=0x0x441710 size=4 free=0x0x0>
> irb(main):010:0> len.struct!('I', 'val')
> => nil
> irb(main):011:0> TestDLL.get_data(data.ref, len)
> => 30
> irb(main):012:0> len['val']
> => 30
> irb(main):013:0> data.to_s
> => "string of size 30"
> irb(main):014:0>

Thanks for this example, it's a little more clear now.  Wouldn't you
want to set len.free to DL::FREE as well?

-- 
Josh Huber