I am building some C++ code that utilises pybind11 to do some wrapping and create a Python extension module, and I am encountering some undefined symbol problems. Upon further examination, it appears to be because certain template function specialisations are not publically visible in the shared library I am building.
I have a MWE to demonstrate explicitly the problem:
symbol_test.hpp
#include <pybind11/pybind11.h>
template <typename T>
void test_func(T var) {}
template <>
void test_func<int>(int);
template <>
void test_func<pybind11::object>(pybind11::object);
symbol_test.cpp
#include "symbol_test.hpp"
template <>
void test_func<int>(int var) {}
template <>
void test_func<pybind11::object>(pybind11::object var) {}
Build command:
g++ -std=c++14 -fPIC -I/home/farmer/anaconda3/envs/default/include/python2.7 -I/home/farmer/repos/pybind11/include -shared -o testlib.so symbol_test.cpp
Inspect library with nm:
nm testlib.so
...
00000000000024d0 T _Z9test_funcIiEvT_
00000000000024da t _Z9test_funcIN8pybind116objectEEvT_
...
In short, the instance of test_func specialised on "int" is visible, but the instance specialised on "pybind11::object" is not. Why? How do I control this? I need the pybind11::object version of the function to be exported in the library, but I don't know why it isn't.
I ask the question here rather than submit it as a pybind11 bug because I just assume there is something I don't understand about how template functions symbols are exported in shared libraries, rather than it being a deficiency in pybind11.
Edit: I had a thought; pybind11 is a header-only library, so I suppose the code for the pybind11::object class is not getting built or something? And this is affecting the visibility of template functions which use it?
来源:https://stackoverflow.com/questions/50673981/visibility-of-template-function-specialisations-in-shared-libraries-dependence