c++c++11pybind11template-classes

How to wrap a shared pointer of a template class function in Pybind11


I want to wrap a shared pointer of a template class function in Pybind11. My class is a template queue : MyQueue.hpp

template<typename Data>
class MyQueue {
    public:
        std::queue <Data> the_queue;
        static std::shared_ptr<MyQueue<Data>> make_data_q_ptr();
};

MyQueue.cpp

template<typename Data>
std::shared_ptr<MyQueue<Data>> MyQueue<Data>::make_data_q_ptr(){
    std::shared_ptr<MyQueue<Data>> data_q_ptr;
    data_q_ptr = std::make_shared<MyQueue<Data>>();
    return data_q_ptr;
}

The type of data in MyQueue : DataType.cpp

class DataType
{
    public:
        uint mynumber;
};

The wrapper using Pybind11 : wrap.cpp

namespace py = pybind11;

PYBIND11_MODULE(mymodule, m){
    
    py::class_<MyQueue<DataType>, std::shared_ptr<MyQueue<DataType>>>(m, "MyQueue_DataType")
            .def(py::init<>())
            .def_static("make_data_q_ptr",&MyQueue<DataType>::make_data_q_ptr);
            
    py::class_<DataType>(m, "DataType")
            .def(py::init<>())
            .def_readwrite("mynumber",&DataType::mynumber);
}

Command to compile the code

g++ -shared -fPIC `pkg-config --cflags --libs opencv` -lpthread -std=c++11 -I./pybind11/include/ `python3.7 -m pybind11 --includes` *.cpp -o mymodule.so `python3.7-config --ldflags`

The code gets compiled successfully, but when I try to import the module that I created "mymodule", I get this error: ImportError: undefined symbol: xxx

>>> import mymodule
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /home/pi/templedpybind11/mymodule.so: undefined symbol: _ZN7MyQueueI8DataTypeE15make_data_q_ptrEv

Can you please help me out? Thank you.


Solution

  • Move

    template<typename Data>
    std::shared_ptr<MyQueue<Data>> MyQueue<Data>::make_data_q_ptr(){
        std::shared_ptr<MyQueue<Data>> data_q_ptr;
        data_q_ptr = std::make_shared<MyQueue<Data>>();
        return data_q_ptr;
    }
    

    into your header file. It isn't visible at the point that needs to see it.