10 messages in com.mysql.lists.ndb-connectorsRe: [Fwd: Re: [Swig-user] C++ wrappin...
FromSent OnAttachments
Monty Taylor07 May 2007 14:52 
Mika Raento07 May 2007 23:37 
Monty Taylor08 May 2007 00:06 
Mika Raento08 May 2007 00:21 
Monty Taylor08 May 2007 00:46 
Mika Raento08 May 2007 00:57 
Mika Raento08 May 2007 01:27 
Mika Raento08 May 2007 01:58 
Mika Raento08 May 2007 03:36 
Monty Taylor08 May 2007 11:05 
Subject:Re: [Fwd: Re: [Swig-user] C++ wrapping question]
From:Monty Taylor (mtay@mysql.com)
Date:05/08/2007 12:46:56 AM
List:com.mysql.lists.ndb-connectors

Mika Raento wrote:

I'm looking into the target-language option. Basically what is needed to do that is to:

1. in each target language, have a place to stash the extra reference (e.g., a module level hash in perl) 2. shadow startTransaction/asynchPrepare to stash an extra reference to Ndb/Ndb+transaction (NdbOperations are owned by the transaction) 3. shadow close/callback to remove the extra reference

Well, you know, it might be possible at the C level per language, too. In Python, I can call Py_INCREF(ob) where ob is a PyObject*, which increments the ref count. Then it would be easy to place a Py_DECREF(ob) in the transaction->close() method wrapper, since I'm sure you don't mind if the object is reaped when it goes out of scope after calling close.

Turns out the other place I did this was C#, not python, actually, and it was all done with typemaps ...

%typemap(cscode) NdbTransaction %{ private Ndb ndbReference; internal void addReference(Ndb ndbref) { ndbReference = ndbref; } %}

%typemap(csout, excode=SWIGEXCODE) NdbTransaction* Ndb::startTransaction { IntPtr cPtr = $imcall;$excode $csclassname ret = null; if (cPtr != IntPtr.Zero) { ret = new $csclassname(cPtr, $owner); ret.addReference(this); } return ret; }

%typemap(csfinalize) NdbTransaction %{ ~$cslassname() { // This is only if we haven't managed to kill this guy yet. // Don't depend on this. ndbReference.closeTransaction(this); Dispose(); } %}

But it was (is) sort of ugly.

Out of these 3. is the only one I'm not sure how to do. I have to find out whether you can shadow the destructor. Shadowing the callback will already give a place to keep the extra reference: create another closure around the callback given by the user-level program that maintains a reference.

It's just a pain that we (well, you, I only care about perl for the moment :-) have to do it for each target language separately.

I'm discovering that there are many things where the swig answer is a little too language specific where it really shouldn't need to be. Oh well... I shouldn't complain too much, I can't imagine how long it would take if we had to do _everything_ by hand. I've gotta do Datetime and Decimal typemaps for each language, I guess refcounting a few objects won't hurt. :)

Hey - while you're look at the callback stashing, check out the directors version of callbacks. I wasn't able to make a very good test case, so they may actually work. I actually got a segfault, but now I'm thinking maybe this was related to the issue you're talking about here? It requires making a class in Perl that derives from BaseCallback and overrides the callback method. You'll also have to add (directors="1") to the %module statement. BUT - it might offer a nice way to hook in the transaction. Or - maybe it's not very perl-ish. I sort of like your anonymous callback method in async.pl and the fact that it works.