c++ - 从通过 dlsym 执行的函数返回 unique_ptr

标签 c++ unique-ptr dlsym extern-c

我有一个位于共享对象中的函数,并使用主程序中的 dlsym 加载并执行。 (共享对象和主程序都是C++)

此函数是否有可能返回 std::unique_ptr

共享对象函数 -

extern "C" {
    unique_ptr<Obj> some_function() {
        return make_unique<Obj>();
    }
}

主程序:

void main_flow() {
    auto handle = dlopen(...);
    FuncPtr func = dlsym(handle, "some_function");
    unique_ptr<Obj> func();
}

最佳答案

是的,是的,有很多警告。首先,在 DSO 接口(interface)中使用 boost 或 STL 有点危险。

  1. std::unique_ptr 因编译器而异
  2. std::unique_ptr 在 C++ 版本之间有所不同
  3. std::unique_ptr 在调试/发布版本之间可能有所不同。

这意味着,如果您在 DSO 接口(interface)中使用 STL 或 boost,则所有 exe 和 dsos 都必须使用使用相同构建标志编译的完全相同版本的 C++ 运行时(如果您喜欢的话,还需要使用相同版本的 boost)。

我建议在 Visual Studio 上使用警告级别 4,它将很好地列出 DSO 界面中的所有上述问题(如 C4251 警告)

至于你的问题,是的,该函数将返回一个 std::unique_ptr,但是你现在正在 DSO 中分配内存,你可能会在 exe 中释放该内存。这在 Windows 世界中可能非常糟糕,您可能会发现调试版本具有不同的堆。尝试释放 EXE 堆中 DSO 分配的对象将引发运行时错误,但通常仅在调试版本中。

你的主要内容应该是这样的:

void main_flow() {
  auto handle = dlopen(...);
  FuncPtr func = (FuncPtr)dlsym(handle, "some_function");
  unique_ptr<Obj> obj = func();
}  

就我个人而言,我建议只返回一个裸指针,并在您的 exe 中对其执行 make_unique 。这至少消除了 C4251 问题,尽管您可能会遇到堆问题(除非您将类类型的析构函数设为虚拟)

关于c++ - 从通过 dlsym 执行的函数返回 unique_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56946595/

相关文章:

c++ - 回溯——用硬币填充网格

c++ - 再谈在智能指针上不进行隐式转换的原因

c++ - dlsym() + RTLD_NEXT 在 Ubuntu 20.04 上无法正常工作

linux - 如何使用 Cython 从 dlfcn.h 中使用 dlsym 加载函数

c++ - 为什么这个 Windows 命令行程序不能将其标准输出重定向到文件?

c++ - 我可以在头文件中定义宏吗?

c++ - 无法使用 QtSQL 编译 Qt 项目(链接器错误)

c++ - 为什么我可以使用 make_unique 创建带有衰减数组指针的 unique_ptr?

c++ - 具有智能指针的非虚拟删除器

c++ - 为 LD_PRELOAD 设置我的库会使某些进程产生加载程序错误