我有一个位于共享库中的函数,并通过主程序中的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();
}

最佳答案

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

  • std::unique_ptr在编译器之间有所不同
  • std::unique_ptr在C++版本之间有所不同
  • std::unique_ptr在调试/发行版之间可能有所不同。

  • 这意味着,如果您在DSO界面中使用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问题,尽管您可能会被堆问题咬伤(除非您将类类型的析构函数设为虚拟)

    08-16 13:46