Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8562975
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T16:51:09+00:00 2026-06-11T16:51:09+00:00

I have the following code, which implements a simple C++ class (ObjWithPyCallback) with a

  • 0

I have the following code, which implements a simple C++ class (ObjWithPyCallback) with a Python callback function. The idea is to call the Python function with “this” as the single argument.

The problem is that since ObjWithPyCallback is a SWIG wrapped object I need the SWIG typeinfo in order to create a Python object.

The problem with this is that it’s inside of the SWIG generated file “ObjWithPyCallback_wrap.cxx”. Can SWIG generate a header file? I have thus far not been able to make this happen.

However, even with a header file there is a circular dependency between SWIG and my main implementation, which is annoying. I’d like to find a way to avoid it if at all possible. Ultimately ObjWithPyCallback ends up in a different shared library than the Python bindings.

Is there a clean way to pull this off? I’m aware of this post, but it only addresses the mechanics of SWIG_NewPointerObj.

Thanks in advance for any help!

Here’s the code:

File: example.py

import cb

def foo(x=None):
    print("Hello from Foo!")
    # I'd like x to be a reference to a ObjWithPyCallback object.
    print(x)

o = cb.ObjWithPyCallback()
o.setCallback(foo)
o.call()

File: ObjWithPyCallback.h

#include <Python.h>

class ObjWithPyCallback 
{
   public:

      ObjWithPyCallback();
      void setCallback(PyObject *callback);
      void call();

      PyObject *callback_;
};

File: ObjWithCallback.cpp

#include "ObjWithPyCallback.h"

#include <iostream>

ObjWithPyCallback::ObjWithPyCallback() : callback_(NULL) {}

void ObjWithPyCallback::setCallback(PyObject* callback)
{
   if (!PyCallable_Check(callback))
   {
      std::cerr << "Object is not callable.\n";
   }
   else
   {
      if ( callback_ ) Py_XDECREF(callback_);
      callback_ = callback;
      Py_XINCREF(callback_);
   }
}

void ObjWithPyCallback::call()
{
   if ( ! callback_ )
   {
      std::cerr << "No callback is set.\n";
   }
   else
   {
      // I want to call "callback_(*this)", how to do this cleanly?
      PyObject *result = PyObject_CallFunction(callback_, "");
      if (result == NULL)
         std::cerr << "Callback call failed.\n";
      else
         Py_DECREF(result);
   }
}

File:: ObjWithPyCallback.i

%module cb
%{
   #include "ObjWithPyCallback.h"
%}

%include "ObjWithPyCallback.h"
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T16:51:10+00:00Added an answer on June 11, 2026 at 4:51 pm

    Below is my working solution for solving this problem. It uses the suggestions from both @omnifarious and @flexo above.

    In particular we create a Callback class with a SWIG director and then derive from it in Python to get the required callback functionality without introducing a circular dependency.

    In addition we provide an interface which allows any Python object that is callable to act as a callback. We achieve this by using the “pythonprend” directive in SWIG to prepend some code to the “setCallback” function. This code simply checks for a callable object and if it finds one, wraps it in an instance of a Callback.

    Finally we deal with the memory issues related to having a C++ class (ObjWithPyCallback) reference a director object (i.e. a subclass of Callback).

    File example.py:

    import cb
    
    class CB(cb.Callback):
        def __init__(self):
            super(CB, self).__init__()
        def call(self, x):
            print("Hello from CB!")
            print(x)
    
    def foo(x):
        print("Hello from foo!")
        print(x)
    
    class Bar:
        def __call__(self, x):
            print("Hello from Bar!")
            print(x)
    
    
    o = cb.ObjWithPyCallback()
    mycb=CB()
    o.setCallback(mycb)
    o.call()
    o.setCallback(foo)
    o.call()
    o.setCallback(Bar())
    o.call()
    

    File ObjWithPyCallback.i:

    %module(directors="1") cb
    %{
       #include "Callback.h"
       #include "ObjWithPyCallback.h"
    %}
    %feature("director") Callback;
    %feature("nodirector") ObjWithPyCallback;
    
    %feature("pythonprepend") ObjWithPyCallback::setCallback(Callback&) %{
       if len(args) == 1 and (not isinstance(args[0], Callback) and callable(args[0])):
          class CallableWrapper(Callback):
             def __init__(self, f):
                super(CallableWrapper, self).__init__()
                self.f_ = f
             def call(self, obj):
                self.f_(obj)
    
          args = tuple([CallableWrapper(args[0])])
          args[0].__disown__()
       elif len(args) == 1 and isinstance(args[0], Callback):
          args[0].__disown__()
    
    
    %}
    
    %include "Callback.h"
    %include "ObjWithPyCallback.h"
    

    File Callback.h:

    #ifndef CALLBACK_H
    #define CALLBACK_H
    
    class ObjWithPyCallback;
    
    class Callback
    {
       public:
          Callback(){}
    
          virtual ~Callback(){}
          virtual void call(ObjWithPyCallback& object){} 
    };
    
    #endif
    

    File ObjWithPyCallback.h:

    #ifndef OBJWITHPYCALLBACK_H
    #define OBJWITHPYCALLBACK_H
    
    class Callback;
    
    class ObjWithPyCallback 
    {
       public:
    
          ObjWithPyCallback();
          ~ObjWithPyCallback();
          void setCallback(Callback &callback);
          void call();
    
       private:
    
          Callback* callback_;
    };
    
    #endif
    

    File ObjWithPyCallback.cpp:

    #include "ObjWithPyCallback.h"
    #include "Callback.h"
    
    #include <iostream>
    
    ObjWithPyCallback::ObjWithPyCallback() : callback_(NULL) {}
    
    ObjWithPyCallback::~ObjWithPyCallback()
    {
    }
    
    void ObjWithPyCallback::setCallback(Callback &callback)
    {
       callback_ = &callback;
    }
    
    void ObjWithPyCallback::call()
    {
       if ( ! callback_ )
       {
          std::cerr << "No callback is set.\n";
       }
       else
       {
          callback_->call(*this);
       }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have the following code which is working, I was wondering if this can
i have the following code which switches some fullscreen-background-images (fadeOut, fadeIn). setInterval(function() { var
I have the following very simple class which looks for the last known user
I have following code which works for radio buttons but need to be changed
I want to know is below code correct ? I have following code which
I have the following code which definitely returns a proper data result if I
I have the following code which is used to upload large files (~6MB) to
I have the following code which is fine if I give invalid parameters (though,
I have the following code which will generate two pdf files containing plots to
I have the following code which utilises Guava's Files.readLines() method: List<String> strings = Lists.newArrayList();

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.