首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由于C++参数的存在,.so似乎没有导出pybind11函数

由于C++参数的存在,.so似乎没有导出pybind11函数
EN

Stack Overflow用户
提问于 2022-04-13 15:49:24
回答 1查看 69关注 0票数 5

我目前正在尝试定义一个共享库,我的目标是从Python扩展和普通的C++应用程序中使用这个库。

我成功地构建了共享库,并尝试将一个简单的C++应用程序链接到它,以测试它的功能,但是链接器将共享库的一个功能视为一个未定义的引用。在检查了nm --demangle --dynamic --defined-only --extern-only libmylib.so之后,我意识到这个函数不是由共享库导出的,但是我不知道为什么。

该函数的签名如下:

代码语言:javascript
复制
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的相关部分:

代码语言:javascript
复制
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

代码语言:javascript
复制
#include <pybind11/stl.h>

namespace Example
{
    void simple_func(std::string some_string);

    void pybind11_func(pybind11::function some_func);
}

example.cc

代码语言:javascript
复制
#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

代码语言:javascript
复制
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,则得到以下结果:

代码语言:javascript
复制
> nm -D libexample.so | grep "func"
00000000000039d9 T _ZN7Example11simple_funcENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

因此,pybind11_func不能导出,而simple_func是正确导出的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-14 13:26:56

命名空间pybind11具有隐藏的可见性。

代码语言:javascript
复制
/usr/include/pybind11/detail/common.h:#    
   define PYBIND11_NAMESPACE pybind11 __attribute__((visibility("hidden")))

因此,与名称空间相关的所有函数(比如从名称空间中带有参数类型)也都是隐藏的。

您可以通过显式地将可见性设置为默认值来覆盖此值:

代码语言:javascript
复制
__attribute__((visibility("default"))) 
void bootstrap_mylib( ... )
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71860358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档