[C++-sig] [Swig-user] A callback function with arguments causes error
Bruce Who
bruce.who.hk at gmail.com
Tue May 15 02:25:30 CEST 2007
Hi, Monty,
Thanks for your code, but I still cannot figure out why it doesnot
work. This is all of my code, it is just the callback example of swig
with a little modification, but it just doesnot work:
// ================== example.h
#include <cstdio>
#include <iostream>
class Callback {
public:
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
// virtual void run() { std::cout << "Callback::run()" << std::endl; }
virtual void run(int* pn) { std::cout << "Callback::run()" << (*pn)
<< std::endl; }
};
class Caller {
private:
Callback *_callback;
public:
Caller(): _callback(0) {}
~Caller() { delCallback(); }
void delCallback() { delete _callback; _callback = 0; }
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
// void call() { if (_callback) _callback->run(); }
void call()
{
if (_callback)
{
int i = 90;
_callback->run(&i);
}
}
};
// ================== example.cxx
#include "example.h"
// ================== example.i
%module(directors="1") example
%{
#include "example.h"
%}
%include "std_string.i"
%feature("director") Callback;
%include "example.h"
@rem ================== build.bat
@rem I compile my code with this bat file
set FILENAME=example
call "D:\program\Microsoft Visual Studio 8\VC\bin\vcvars32"
swig -c++ -python %FILENAME%.i
cl -c %FILENAME%_wrap.cxx -ID:\program\Python25\include\
link /subsystem:windows /LIBPATH:D:\program\Python25\libs\
%FILENAME%_wrap.obj /dll /OUT:_%FILENAME%.pyd
#===================================================
# file: runme.py
# you can test the wrapper with this script
import example
class PyCallback(example.Callback):
def __init__(self):
example.Callback.__init__(self)
def run(self, i):
print "PyCallback.run()", i
# Create an Caller instance
caller = example.Caller()
# Add a simple C++ callback (caller owns the callback, so
# we disown it first by clearing the .thisown flag).
print "Adding and calling a normal C++ callback"
print "----------------------------------------"
callback = example.Callback()
callback.thisown = 0
caller.setCallback(callback)
caller.call()
caller.delCallback();
print
print "Adding and calling a Python callback"
print "------------------------------------"
# Add a Python callback (caller owns the callback, so we
# disown it first by calling __disown__).
caller.setCallback(PyCallback().__disown__())
caller.call()
caller.delCallback()
print
print "Adding and calling another Python callback"
print "------------------------------------------"
# Lets do the same but use the weak reference this time.
callback = PyCallback().__disown__()
caller.setCallback(callback)
caller.call()
caller.delCallback()
# All done.
print
print "python exit"
After compiling all code, I run it:
E:\test>runme.py
Adding and calling a normal C++ callback
----------------------------------------
Callback::run()90
Callback::~Callback()
Adding and calling a Python callback
------------------------------------
PyCallback.run()
and then a windows message box pops up saying that there is something
wrong with python.exe.
On 5/15/07, Monty Taylor <monty at inaugust.com> wrote:
> Hi Bruce,
>
> I'm using a callback with arguments from Python using directors.
>
> I've got this:
>
> class BaseCallback {
> public:
> virtual ~BaseCallback() {};
> virtual void callback(int res, NdbTransaction * trans);
>
> };
>
>
> Then from python:
>
> class PythonCallback(ndbapi.BaseCallback):
>
> def __init__(self, recAttr):
> self.recAttr=recAttr
>
> def __call__(self, *args, **kw):
> self.callback(*args,**kw)
>
> def callback(self, ret, myTrans):
> x=self.recAttr.get_value()
>
> Works like a charm. Are you sure everything is working right with memory
> ownership and that int *? I'd try it with just a normal int first to see
> if that's the problem, then go in and figure out how to get Python to
> allocate and pass the int* in such a way that it still exists when you
> access it in the callback... but I could be way off base there.
>
> Monty
More information about the Cplusplus-sig
mailing list