由于 pybind11 参数,.so 似乎未导出 C++ 函数
C++ function not exported by .so seemingly because of pybind11 parameters
我目前正在尝试定义一个共享库,我打算从 Python C++ 扩展以及普通 C++ 应用程序中使用它。
我设法构建了共享库,并尝试 link 一个简单的 C++ 应用程序来测试它的功能,但是共享库的一个函数被 link呃。在检查 nm --demangle --dynamic --defined-only --extern-only libmylib.so
后,我意识到共享库没有导出该函数,但我不知道为什么。
函数的签名如下:
void bootstrap_mylib(std::vector<std::string> python_path,
std::vector<std::string> python_scripts,
std::string interface_module,
std::function<void (pybind11::module_, pybind11::object)> interface_module_initializer);
如果我注释掉最后一个参数,一切顺利,所以问题似乎出在我以某种方式声明与 pybind11 的依赖关系的方式。
以下是我的CMakeLists.txt的相关部分:
set(CMAKE_CXX_COMPILER /usr/bin/g++)
project(monilog LANGUAGES CXX VERSION 0.0.1)
set(PYBIND11_PYTHON_VERSION 3.8)
find_package(pybind11 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
add_library(mylib SHARED MyLib.cc MyLib.h)
set_property(TARGET mylib PROPERTY CXX_STANDARD 17)
target_link_libraries(mylib ${PYTHON_LIBRARIES})
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
set_target_properties(mylib PROPERTIES SOVERSION 1)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER MyLib.h)
知道我做错了什么吗?
编辑:最小工作示例
这是我的问题的一个最小示例,由以下文件组成:
example.h
#include <pybind11/stl.h>
namespace Example
{
void simple_func(std::string some_string);
void pybind11_func(pybind11::function some_func);
}
example.cc
#include "example.h"
namespace Example
{
void simple_func(std::string some_string)
{
std::cout << "Simple function" << '\n';
}
void pybind11_func(pybind11::function some_func)
{
std::cout << "Pybind11 function" << '\n';
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
cmake_policy(SET CMP0074 NEW)
# SET VARIABLES
set(CMAKE_CXX_COMPILER /usr/bin/g++)
set(CMAKE_CXX_STANDARD 17)
project(example CXX)
set(PYBIND11_PYTHON_VERSION 3.8)
find_package(pybind11 REQUIRED)
# include_directories(${PYTHON_INCLUDE_DIRS})
include_directories(${pybind11_INCLUDE_DIRS})
add_library(example SHARED example.cc example.h)
target_link_libraries(example ${PYTHON_LIBRARIES})
当我构建项目时,如果我在暴露的符号中搜索 func
,我会得到以下结果:
> nm -D libexample.so | grep "func"
00000000000039d9 T _ZN7Example11simple_funcENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
pybind11_func
因此不导出,而 simple_func
正确导出。
命名空间 pybind11
具有隐藏的可见性。
/usr/include/pybind11/detail/common.h:#
define PYBIND11_NAMESPACE pybind11 __attribute__((visibility("hidden")))
因此所有与该命名空间有任何关系的函数(例如从中获取参数类型)也被隐藏。
您可以通过将可见性显式设置为默认值来覆盖它:
__attribute__((visibility("default")))
void bootstrap_mylib( ... )
我目前正在尝试定义一个共享库,我打算从 Python C++ 扩展以及普通 C++ 应用程序中使用它。
我设法构建了共享库,并尝试 link 一个简单的 C++ 应用程序来测试它的功能,但是共享库的一个函数被 link呃。在检查 nm --demangle --dynamic --defined-only --extern-only libmylib.so
后,我意识到共享库没有导出该函数,但我不知道为什么。
函数的签名如下:
void bootstrap_mylib(std::vector<std::string> python_path,
std::vector<std::string> python_scripts,
std::string interface_module,
std::function<void (pybind11::module_, pybind11::object)> interface_module_initializer);
如果我注释掉最后一个参数,一切顺利,所以问题似乎出在我以某种方式声明与 pybind11 的依赖关系的方式。
以下是我的CMakeLists.txt的相关部分:
set(CMAKE_CXX_COMPILER /usr/bin/g++)
project(monilog LANGUAGES CXX VERSION 0.0.1)
set(PYBIND11_PYTHON_VERSION 3.8)
find_package(pybind11 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
add_library(mylib SHARED MyLib.cc MyLib.h)
set_property(TARGET mylib PROPERTY CXX_STANDARD 17)
target_link_libraries(mylib ${PYTHON_LIBRARIES})
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
set_target_properties(mylib PROPERTIES SOVERSION 1)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER MyLib.h)
知道我做错了什么吗?
编辑:最小工作示例
这是我的问题的一个最小示例,由以下文件组成:
example.h
#include <pybind11/stl.h>
namespace Example
{
void simple_func(std::string some_string);
void pybind11_func(pybind11::function some_func);
}
example.cc
#include "example.h"
namespace Example
{
void simple_func(std::string some_string)
{
std::cout << "Simple function" << '\n';
}
void pybind11_func(pybind11::function some_func)
{
std::cout << "Pybind11 function" << '\n';
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
cmake_policy(SET CMP0074 NEW)
# SET VARIABLES
set(CMAKE_CXX_COMPILER /usr/bin/g++)
set(CMAKE_CXX_STANDARD 17)
project(example CXX)
set(PYBIND11_PYTHON_VERSION 3.8)
find_package(pybind11 REQUIRED)
# include_directories(${PYTHON_INCLUDE_DIRS})
include_directories(${pybind11_INCLUDE_DIRS})
add_library(example SHARED example.cc example.h)
target_link_libraries(example ${PYTHON_LIBRARIES})
当我构建项目时,如果我在暴露的符号中搜索 func
,我会得到以下结果:
> nm -D libexample.so | grep "func"
00000000000039d9 T _ZN7Example11simple_funcENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
pybind11_func
因此不导出,而 simple_func
正确导出。
命名空间 pybind11
具有隐藏的可见性。
/usr/include/pybind11/detail/common.h:#
define PYBIND11_NAMESPACE pybind11 __attribute__((visibility("hidden")))
因此所有与该命名空间有任何关系的函数(例如从中获取参数类型)也被隐藏。
您可以通过将可见性显式设置为默认值来覆盖它:
__attribute__((visibility("default")))
void bootstrap_mylib( ... )