E
Erwan Loisant
Hello.
I am still in my binding thing; actually the structure I want to bind
is an oriented graph structure (a Galois' Lattice to be precise). So I
have 2 class (as well in C as in Ruby): GaloisNode and GaloisLattice.
Each GaloisNode structure contains links to neighbors.
For now, I wrap my C GaloisLattice structure, and I have observer
methods to look at my nodes. Basically I have a "nodes" methods
returning the list of nodes. And this is the problem.
I just wrap each node into a ruby GaloisNode and return an array
containing all the nodes. Note that since these C objects are used by
the lattice I don't want Ruby to delete them, so I pass "0" as the
argument for the "free" function.
The problem is that if I do that:
myLattice = GaloisLattice.new
[ Adding elements, building a big lattice... ]
allNodes = GaloisLattice.nodes
[ Modifying the lattice, including deleting nodes ]
allNodes
....Then allNodes will contain GaloisNode wrapping a NULL element, which
is bad. Next time I try to access it I get a segfault for sure.
I think that the problem is that my library is written in pure C (and I
would like it to remain an independant C library) and in this library I
create, delete elements and add, remove references; Ruby's garbage
collector doesn't know about these modifications and can not know about
that.
What could be a better design? I there a way to design my C library
better so I can tell Ruby's garbage collector about references without
introducing a Ruby dependency in my library's source code ?
I have thought about returning a copy of node elements instead of
wrapping them, but since each nodes contains references to neighbors I
would have to duplicate the whole graph (which is supposed to grow
big).
I am still in my binding thing; actually the structure I want to bind
is an oriented graph structure (a Galois' Lattice to be precise). So I
have 2 class (as well in C as in Ruby): GaloisNode and GaloisLattice.
Each GaloisNode structure contains links to neighbors.
For now, I wrap my C GaloisLattice structure, and I have observer
methods to look at my nodes. Basically I have a "nodes" methods
returning the list of nodes. And this is the problem.
I just wrap each node into a ruby GaloisNode and return an array
containing all the nodes. Note that since these C objects are used by
the lattice I don't want Ruby to delete them, so I pass "0" as the
argument for the "free" function.
The problem is that if I do that:
myLattice = GaloisLattice.new
[ Adding elements, building a big lattice... ]
allNodes = GaloisLattice.nodes
[ Modifying the lattice, including deleting nodes ]
allNodes
....Then allNodes will contain GaloisNode wrapping a NULL element, which
is bad. Next time I try to access it I get a segfault for sure.
I think that the problem is that my library is written in pure C (and I
would like it to remain an independant C library) and in this library I
create, delete elements and add, remove references; Ruby's garbage
collector doesn't know about these modifications and can not know about
that.
What could be a better design? I there a way to design my C library
better so I can tell Ruby's garbage collector about references without
introducing a Ruby dependency in my library's source code ?
I have thought about returning a copy of node elements instead of
wrapping them, but since each nodes contains references to neighbors I
would have to duplicate the whole graph (which is supposed to grow
big).