[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 {
	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 {
	Callback *_callback;
	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;

// ================== 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):
    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

print "Adding and calling a Python callback"
print "------------------------------------"

# Add a Python callback (caller owns the callback, so we
# disown it first by calling __disown__).


print "Adding and calling another Python callback"
print "------------------------------------------"

# Lets do the same but use the weak reference this time.

callback = PyCallback().__disown__()

# All done.

print "python exit"

After compiling all code, I run it:
Adding and calling a normal C++ callback

Adding and calling a Python callback

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