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

Returning unique_ptr from a function executed via dlsym

本文关键字:返回 unique ptr 函数 DLSYM 执行      更新时间:2023-10-16

i具有一个位于共享对象中的函数,并从主程序中加载和执行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接口中使用Boost或STL有点危险。

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

这意味着,如果您在DSO接口中使用STL或Boost,则所有EXES和DSO都必须使用相同的构建标志(如果是您的事物(使用相同的构建标志的C 运行时版本完全相同。

我建议在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。尽管您可能会被堆问题咬伤(除非您将类型类型的deStructor咬伤(

,但这至少会消除C4251问题