What Is The Cleanest Way to Call A Python Function From C++ with a SWIG Wrapped Object

后端 未结 3 575
Happy的楠姐
Happy的楠姐 2021-01-31 05:54

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

3条回答
  •  太阳男子
    2021-01-31 06:42

    1. General idea of solve the problem:

    (1). Define a C++ class named Callback, which has a method run().

    (2). Inherit Callback in Python code, and create a instance.

    (3). Use C++ method to bind the instance to C++ pointor.

    (4). Use the pointor to access run(), which is defined in python code.

    2. Sample code

    (1). example.h

    class Callback{
        public:
        virtual void run(int n);                                                                                                                                                      
        virtual ~Callback() {}; 
    };   
    extern Callback * callback;
    extern void doSomeWithCallback();
    extern void setCallback(Callback * cb);
    

    (2). example.cxx

    #include 
    #include "example.h"
    
    int n=0;
    Callback * callback = NULL;
    
    void Callback::run(int n){ 
        std::cout << "This print from C++: n = " << n << std::endl;
    }    
    
    void setCallback(Callback * cb){
        callback = cb; 
    }    
    
    void doSomeWithCallback(){
        if(callback == NULL){
            std::cout << "Must set callback first!" << std::endl;
        }else{
            callback->run(n++);
        }                                                                                                                                                                                         
    }
    

    (3). example.i

    /* File : example.i */                                                                                                                                                                        
    %module(directors="1") example
    %{
    #include "example.h"                                                                                                                                                                          
    %}
    
    /* turn on director wrapping Callback */
    %feature("director") Callback;
    
    %include "example.h"
    

    3. Compile

    $ swig -c++ -python example.i
    $ g++ -c -fPIC example.cxx example_wrap.cxx -I/usr/include/python2.7/
    $ g++ -shared example.o example_wrap.o -o _example.so
    

    4. Use in python shell

    In [1]: import example
    
    In [2]: example.doSomeWithCallback()
    Must set callback first!
    
    In [3]: callback = example.Callback()
    
    In [4]: example.setCallback(callback)
    
    In [5]: example.doSomeWithCallback()
    This print from C++: n = 0
    
    In [6]: class Callback(example.Callback):
       ...:     def run(self, n):
       ...:         print 'This print from Python: n =', n
       ...:         
    
    In [7]: callback =  Callback()
    
    In [8]: example.setCallback(callback)
    
    In [9]: example.doSomeWithCallback()
    This print from Python: n = 1
    

    5. Other

    I think there's more thing you need. Try:

    $ ls swig-x.x.x/Examples/python
    

提交回复
热议问题