为什么 dlopen 函数内传递的 std::any 的 std::any_cast 会引发错误

2024-01-02

我正在摆弄 c++17 和插件,并且遇到了一个无法解决的错误。在下面的 MWE 中,我可以调用一个本地函数,该函数接受std::any,当我尝试阅读内容时,一切都按预期进行。当我通过插件(dlopen)加载这个完全相同的函数时,它正确地看到了any上的类型,但它不能std::any_cast内容。

对于找出导致此错误的原因,我们将不胜感激。

这是我的环境、MWE 以及由此产生的错误。

>> g++ --version

g++ (GCC) 7.1.1 20170526 (Red Hat 7.1.1-2)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

>> scons --version

SCons by Steven Knight et al.:
    script: v2.5.1.rel_2.5.1:3735:9dc6cee5c168[MODIFIED], 2016/11/03 14:02:02, by bdbaddog on mongodog
    engine: v2.5.1.rel_2.5.1:3735:9dc6cee5c168[MODIFIED], 2016/11/03 14:02:02, by bdbaddog on mongodog
    engine path: ['/usr/lib/scons/SCons']
Copyright (c) 2001 - 2016 The SCons Foundation

>> tree

.
├── SConstruct
└── src
    ├── main.cpp
    ├── plugin.cpp
    └── SConscript

1 directory, 4 files

>> cat SConstruct

SConscript('src/SConscript', variant_dir='build', duplicate=0)

>> cat src/SConscript

env = Environment()
env.Append(CXXFLAGS=['-std=c++17'])
plugin = env.SharedLibrary('plugin', 'plugin.cpp')
Install('../lib', plugin)
driver_env = env.Clone()
driver_env.Append(LIBS=['dl', 'stdc++fs'])
driver = driver_env.Program('driver', 'main.cpp')
Install('../bin', driver)

>> cat src/plugin.cpp

#include <any>
#include <iostream>
using namespace std;
extern "C" {
int plugin(any& context) {
    cout << "    Inside Plugin" << endl;
    cout << "    Has Value? " << context.has_value() << endl;
    cout << "    Type Name: " << context.type().name() << endl;
    cout << "    Value: " << any_cast<double>(context) << endl;
}
}

>> cat src/main.cpp

#include <functional>
#include <iostream>
#include <stdexcept>
#include <any>
#include <experimental/filesystem>
#include <dlfcn.h>

using namespace std;
using namespace std::experimental;

function< void(any&) > loadplugin(string filename) {
    function< void(any&) > plugin;
    filesystem::path library_path(filename);
    filesystem::path library_abspath = canonical(library_path);
    void * libraryHandle = dlopen(library_abspath.c_str(), RTLD_NOW);
    if (!libraryHandle) {
        throw runtime_error("ERROR: Could not load the library");
    }
    plugin = (int(*) (any&))dlsym(libraryHandle, "plugin");
    if (!plugin) {
        throw runtime_error("ERROR: Could not load the plugin");
    }
    return plugin;
}

int local(any& context) {
    cout << "    Inside Local" << endl;
    cout << "      Has Value? " << context.has_value() << endl;
    cout << "      Type Name: " << context.type().name() << endl;
    cout << "      Value: " << any_cast<double>(context) << endl;
}

int main(int argc, char* argv[]) {
    cout << "  Resolving Paths..." << endl;
    filesystem::path full_path = filesystem::system_complete( argv[0] ).parent_path();
    filesystem::path plugin_path(full_path/".."/"lib"/"libplugin.so");
    cout << "  Creating Context..." << endl;
    any context(.1);
    cout << "  Loading Plugin..." << endl;
    function<void(any&) > plugin = loadplugin(plugin_path.string());
    cout << "  Calling Local..." << endl;
    local(context);
    cout << "  Calling Plugin..." << endl;
    plugin(context);
}

>> scons

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o build/main.o -c -std=c++17 src/main.cpp
g++ -o build/driver build/main.o -ldl -lstdc++fs
Install file: "build/driver" as "bin/driver"
g++ -o build/plugin.os -c -std=c++17 -fPIC src/plugin.cpp
g++ -o build/libplugin.so -shared build/plugin.os
Install file: "build/libplugin.so" as "lib/libplugin.so"
scons: done building targets.

>> tree

.
├── bin
│   └── driver
├── build
│   ├── driver
│   ├── libplugin.so
│   ├── main.o
│   └── plugin.os
├── lib
│   └── libplugin.so
├── SConstruct
└── src
    ├── main.cpp
    ├── plugin.cpp
    └── SConscript

4 directories, 10 files

>> bin/driver

  Resolving Paths...
  Creating Context...
  Loading Plugin...
  Calling Local...
    Inside Local
      Has Value? 1
      Type Name: d
      Value: 0.1
  Calling Plugin...
    Inside Plugin
    Has Value? 1
    Type Name: d
terminate called after throwing an instance of 'std::bad_any_cast'
  what():  bad any_cast
    Value: Aborted (core dumped)

libstdc++ 的any依赖于程序内相同模板实例化的地址是相同的,这意味着您需要如果您正在使用,请采取预防措施dlopen https://gcc.gnu.org/faq.html#dso:

编译器必须发出 [具有模糊链接的对象,例如模板 实例化]在任何需要它们存在的翻译单元中, 然后依靠链接和加载过程来确保 只有其中之一在最终的可执行文件中处于活动状态。带静电 链接所有这些符号都在链接时解析,但是 动态链接,在加载时进行进一步解析。你必须 确保共享库中的对象被解析 可执行文件和其他共享库中的对象。

  • 对于链接到共享库的程序,不需要额外的预防措施。
  • 您无法使用以下命令创建共享库-Bsymbolic选项,因为这会阻止上述解决方案。
  • 如果你使用dlopen要从共享库显式加载代码,您必须执行几件事。首先,从 通过将其链接到可执行文件-E标志(您必须指定 这作为-Wl,-E如果您以通常的方式调用链接器 来自编译器驱动程序 g++)。您还必须使外部 加载的库中的符号可用于后续库 提供RTLD_GLOBAL标记为dlopen。符号分辨率 可以是立即的,也可以是惰性的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 dlopen 函数内传递的 std::any 的 std::any_cast 会引发错误 的相关文章

  • 将复选框添加到 UniformGrid

    我正在尝试将复选框动态添加到 wpf 中的统一网格中 但看起来网格没有为它们分配足够的空间 所以它们都有点互相重叠 这就是我将它们添加到后面的代码中的方法 foreach string folder in subfolders PathCh
  • 是否可以强制 XMLWriter 将元素写入单引号中?

    这是我的代码 var ptFirstName tboxFirstName Text writer WriteAttributeString first ptFirstName 请注意 即使我使用 ptFirstName 也会以双引号结束 p
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • Validation.ErrorTemplate 的 Wpf 动态资源查找

    在我的 App xaml 中 我定义了一个资源Validation ErrorTemplate 这取决于动态BorderBrush资源 我打算定义独特的BorderBrush在我拥有的每个窗口以及窗口内的不同块内
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver
  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • 是否可以仅使用标准 C++ 为 Windows Phone 7 进行编程?

    我知道Windows Phone 7开发的推荐语言是C 然而 由于各种原因 我非常喜欢继续在standardC 如果可能的话 是否可以仅使用标准 C 为 Windows Phone 7 进行编程 如果答案是肯定的 我需要哪些工具和资源来实现
  • OpenCV cv::findHomography 运行时错误

    我用来编译和运行代码Features2D 单应性查找已知对象 http opencv itseez com doc tutorials features2d feature homography feature homography htm
  • 在DataGridView中使用DataTable显示小图片(Icon)

    EDIT 我想使用 DataTable 在 Datagridview 中使用图像 RadioButton 只是本文的一个简单问题格式 让我澄清一下这一点 如何使用绑定样式在 datagridview 上添加这个 图像 或那个 图像 因为 我
  • Zend框架2:如何全局设置区域设置?

    我必须根据用户想要的语言动态更改区域设置 我可以在 Application Module php 中设置区域设置 如下所示 public function onBootstrap MvcEvent e translator e gt get
  • 数据集中的标题 (Matlab)

    我找不到关于 dataset 的任何好的文档 所以这就是为什么我想问你们 我会简短地回答这个问题 我可以在数据集中设置标题 列标题 而不将数据输入到数据集中吗 我想不是 所以问题的第二部分是 我可以制作一个单行数据集 在其中用空数据命名标题
  • LLVM 中的参数转发

    我需要一些关于 转发 参数给被调用者 在 LLVM IR 中 的建议 假设我有一个函数F这就是开头所说的all模块中的其他功能 从F我需要访问 读取 传递给其直接调用者的参数 现在要做到这一点 我将调用者中的所有参数放入一个结构体中 并传递
  • 在 C++11 中使用 future、异步和线程实现搜索

    我想以多线程方式实现分支定界搜索 特别是 我想使用async包装每个分支的搜索调用 然后等待某个线程给出答案 然后退出 理想情况下 我想取消其他线程 但线程取消不在标准中 这是一些简化的代码 include
  • 测验游戏的线程计时器

    我必须在大学里用 Python 做一些练习 所以我需要构建一个问答游戏 要求是 正确答案得 1分 错误答案得 1分 玩家必须在 20 秒内回答每个问题 如果玩家回答的时间超过 20 秒 即使他的回答正确 他也会得到 1 分 我刚刚尝试过th
  • SurfaceView示例代码

    我需要 Android 的示例教程SurfaceView 或者使用它的可以共享的示例代码 API 演示对我来说很难理解 有人有替代方案吗 这次提交 https github com johnnylambada WorldMap commit
  • 如何在 Spring Boot 集成测试中自动装配存储库?

    我正在尝试编写集成测试 但在测试中自动装配存储库时遇到问题 我收到这个异常 org springframework beans BeanInstantiationException 无法实例化 org observer media repo
  • 如何告诉 VS Code 格式文档在一定长度后换行? [复制]

    这个问题在这里已经有答案了 In Visual Studio Code when you press ALT SHIFT F to format HTML document VS Code would wrap a line that is
  • MailChimp 合并变量除了 FNAME 和 LNAME 之外还接受什么?

    我已经使用电子邮件地址 姓名实现了非常基本的注册 尽管我现在想添加额外的数据 例如电话号码 网站等 我的问题是在哪里API doc http apidocs mailchimp com api 1 3 我能找到除了 FNAME 和 LNAM
  • Android 中的 SQLite 查询来计算行数

    我正在尝试创建一个简单的登录表单 将在登录屏幕上输入的登录 ID 和密码与存储在数据库中的登录 ID 和密码进行比较 我正在使用以下查询 final String DATABASE COMPARE select count from use
  • 如何在django多表继承中将现有父级与子级关联

    我有一个现有的父实体 其中包含许多现有记录 class Entity models Model name models CharField Name max length 64 db index True 我还有使用 django 多表继承
  • React-bootstrap 选项卡 - 内容未显示

    选项卡不显示内容并且选项卡上没有样式 选项卡不显示内容 这是代码 我该如何解决这个问题 我究竟做错了什么 这段代码与react bootstrap页面上的代码几乎相似 simple tabs js import React Componen
  • 如何在javascript中获取div和完整的内部内容?

    我想在 javascript 中获取 div 内部内容 Ex div style height 20px content br content br content br div 这是我的 html 代码 我只知道div id 内容 但我想
  • 获取 Python 系统调用作为字符串结果

    我想用os system md5sum myFile 并从 os system 返回结果 而不是仅仅在回显的子 shell 中运行 简而言之 我想这样做 resultMD5 os system md5sum myFile 并且 result
  • 有没有像“cvHoughCircles()”这样的opencv函数用于方形检测?

    有没有像 cvHoughCircles 这样的opencv函数可以用于方形检测编程 对于圆检测程序来说CvSeq 圆 cvHoughCircles 但我找不到方形检测 您不需要任何单独的功能 OpenCV 附带了正方形检测示例 它实际上检测
  • Web 应用程序中的单例模式

    我在 Web 应用程序中对数据上下文使用单例模式 这样我就不必每次都实例化它 但是我不确定 Web 应用程序如何工作 IIS 是否为每个连接的用户打开一个线程 如果是这样 如果我的单例不是线程安全的 会发生什么 另外 对数据上下文使用单例模
  • 为什么 dlopen 函数内传递的 std::any 的 std::any_cast 会引发错误

    我正在摆弄 c 17 和插件 并且遇到了一个无法解决的错误 在下面的 MWE 中 我可以调用一个本地函数 该函数接受std any 当我尝试阅读内容时 一切都按预期进行 当我通过插件 dlopen 加载这个完全相同的函数时 它正确地看到了a