2016-10-04 10 views
1

pybind11로 파이썬 바인딩을 생성하려고합니다. C++ 인스턴스에서 메모리가 처리되는 C++ 인스턴스를 참조합니다. 내가 파이썬 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

나는 내 자신의 질문에 대한 답을 찾았습니다. 트릭은 다음 두 개념의 조합입니다.

  • 싱글 톤을 반환하는 독립 함수를 만듭니다.
  • 생성자를 바인딩하는없이 의 단일 클래스에 바인딩을 만듭니다.

    #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); 
    } 
    
    :

다음의 예는이 기술을 도시