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

时间:2019-07-09 06:38:02

标签: 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();
}

1 个答案:

答案 0 :(得分:1)

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

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

这意味着,如果您在DSO界面中使用STL或boost,则所有exe和dsos必须使用完全相同版本的C ++运行时,并带有相同的构建标志(如果您使用的是boost,则使用相同的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问题,尽管您可能会被堆问题咬住(除非您将类类型的析构函数设为虚拟)