[Pyrex] C++, references, deref a pointer...
Lenard Lindstrom
len-l at telus.net
Sat Apr 8 05:05:19 CEST 2006
On 7 Apr 2006 at 11:52, John Sutherland wrote:
> Hi all... I've been working with Lenard's C++ patches, and found one
> problem, and have some other questions..
>
> The problem I found is when trying his example to wrap C++ methods
> from a previous post (in repsonse to someone else's C++ wrapper).. I
> wasn't able to get it to recongize the C++ methods of a class.. i
> would get errors say that it the class stucture didn't have that
> attirbute.. So I had to modify Compler/ExprNodes.py to handle it:
>
> Approx line 1576 was:
> if entry.is_variable or entry.is_cmethod:
> to
> if entry.is_variable or entry.is_cmethod or entry.is_cfunction:
>
I do not understand this change. An extension class attribute cannot
be a C function. It can be a C function pointer, which is just a C
attribute. See below.
> then I was able to compile, and it seems to work..
>
> Now for my questions...
> I have a couple classes I'm wrapping where one of them takes a
> reference to the other, and I can't seem to figure out the magic to
> get it to work...
>
> Example (not from actaul code. forgive mistakes):
>
> class Record {
> Record()
> ~Record()
> }
>
> class Set {
> Set()
> ~Set()
> addRecord( Record& )
> }
>
> Python:
> cdef extern from "../rrec.h":
> ctypedef struct record "Record":
> <sturct full of functions>
> record *myRecordFactory "new Record" ()
>
> cdef extern from "../rrset.h":
> ctypedef struct rrset "RRSet":
> int addRecord "addRecord" ( record )
> rrset *myRRSetFactory "new RRSet" ()
>
int (*addRecord) "addRecord" (record)
Treat C++ methods as function pointers.
> cdef class Record:
> cdef rrec *thisptr
>
> def __init__(self):
> self.thisptr = myRecordFactory()
>
>
> cdef class RRSet:
> cdef rrset *thisptr
> def __init__(self):
> self.thisptr = myRRSetFactory()
>
> def addRR( self, RRec rr not None):
> self.thisptr.addRR( <rrec>rr.thisptr )
>
> I can't seem to figure out the mojo to get the cast right... I can't
> seem to deref the pointer, or be able to get a reference...
>
>
> Any ideas?
>
cdef class RRSet:
...
def addRR(self, Record rr not None):
self.thisptr.addRecord(rr.thisptr[0])
Declaring rr as Record allows access to its C field thisptr; no
recasting is necessary. addRecord expects a C++ reference so pointer
rr.thisptr has to be dereferenced.
The following example is tested with GCC and Python 2.4 on Windows:
--- Klass.h ---
class Record
{
public:
Record(int i);
~Record();
int i;
};
Record::Record(int i)
{
this->i = i;
}
Record::~Record()
{
this->i = 0;
}
class Set
{
public:
int AddRecord(Record &r);
};
int Set::AddRecord(Record &r)
{
return r.i;
}
--- record.pyx ---
cdef extern from "Klass.h":
struct record "Record":
pass
struct record_set "Set":
int (* AddRecord)(record r)
record *RecordFactory "new Record" (int i)
record_set *SetFactory "new Set" ()
void delete "delete " (void *o)
cdef class Record:
cdef record *thisptr
def __new__(self, int i):
self.thisptr = RecordFactory(i)
def __dealloc__(self):
delete(self.thisptr)
cdef class Set:
cdef record_set *thisptr
def __new__(self):
self.thisptr = SetFactory()
def __dealloc__(self):
delete(self.thisptr)
def AddRecord(self, Record r not None):
print self.thisptr.AddRecord(r.thisptr[0])
Lenard Lindstrom
<len-l at telus.net>
More information about the Pyrex
mailing list