2016-10-04 8 views
1

私は、メモリがC++側で処理されるC++インスタンスを参照するpybind11でPythonバインディングを作成しようとしています。私のpython example.dogの間のリンクを作成する方法についてこだわっているpybind11でC++に割り当てられたオブジェクトを参照する

import <pybind11/pybind11> 

struct Dog { 
    void bark() { printf("Bark!\n"); } 
}; 

int main() 
{ 
    auto dog = new Dog; 
    Py_Initialize(); 
    initexample(); // Initialize the example python module for import 

    // TBD - Add binding between dog and example.dog . 

    PyRun_StringFlags("import example\n" 
        "\n" 
        "example.dog.bark()\n" // Access the C++ allocated object dog. 
        , Py_file_input, main_dict, main_dict, NULL); 
    Py_Finalize(); 
} 

およびC++ dog変数:ここではいくつかのサンプルコードです。

私はDogの新しいインスタンスを割り当てますが、それは私が望むものではないため、py:class_<Dog>.def(py::init<>())を使用することはできません。

答えて

2

私自身の質問に対する回答が見つかりました。このトリックは、次の2つの概念の組み合わせです。

  • シングルトンを返す独立した関数を作成します。
  • シングルトンクラスへのバインディングを作成バインディングなしでコンストラクタをバインドします。

    #include <Python.h> 
    #include <pybind11/pybind11.h> 
    
    namespace py = pybind11; 
    using namespace pybind11::literals; 
    
    // Singleton to wrap 
    struct Singleton 
    { 
        Singleton() : x(0) {} 
    
        int exchange(int n) // set x and return the old value 
        { 
        std::swap(n, x); 
        return n; 
        } 
    
        // Singleton reference 
        static Singleton& instance() 
        { 
        static Singleton just_one; 
        return just_one; 
        } 
    
        int x; 
    }; 
    
    PYBIND11_PLUGIN(example) { 
        py::module m("example", "pybind11 example plugin"); 
    
        // Use this function to get access to the singleton 
        m.def("get_instance", 
          &Singleton::instance, 
          py::return_value_policy::reference, 
          "Get reference to the singleton"); 
    
        // Declare the singleton methods 
        py::class_<Singleton>(m, "Singleton") 
         // No init! 
         .def("exchange", 
          &Singleton::exchange, 
          "n"_a, 
          "Exchange and return the current value" 
          ) 
         ; 
    
        return m.ptr(); 
    } 
    
    int main(int argc, char **argv) 
    { 
        Py_Initialize(); 
    
        PyObject* main_module = PyImport_AddModule("__main__"); 
        PyObject* main_dict = PyModule_GetDict(main_module); 
    
        initexample(); 
    
        // Call singleton from c++ 
        Singleton::instance().exchange(999); 
    
        // Populate the example class with two static pointers to our instance. 
        if (PyRun_StringFlags("import example\n" 
             "\n" 
             "example.s1 = example.get_instance()\n" 
             "example.s2 = example.get_instance()\n", 
             Py_file_input, main_dict, main_dict, NULL) == nullptr) 
         PyErr_Print(); 
    
        // Test referencing the singleton references 
        if (PyRun_StringFlags("from example import *\n" 
             "\n" 
             "for i in range(3):\n" 
             " print s1.exchange(i*2+1)\n" 
             " print s2.exchange(i*2+2)\n" 
             "print dir(s1)\n" 
             "print help(s1.exchange)\n" 
             , 
             Py_file_input, main_dict, main_dict, NULL) == nullptr) 
         PyErr_Print(); 
    
        Py_Finalize(); 
    
        exit(0); 
    } 
    

次の例では、技術を示します

関連する問題