从通过 dlsym 执行的函数返回 unique_ptr
Returning unique_ptr from a function executed via dlsym
我有一个位于共享对象中的函数,它是用 dlsym
从主程序加载和执行的。
(共享对象和主程序都是C++)
这个函数有没有可能 return 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 有点危险。
- std::unique_ptr 编译器之间存在差异
- std::unique_ptr 不同 C++ 版本
- std::unique_ptr 可能在 debug/release 版本之间有所不同。
这意味着如果您在 DSO 接口中使用 STL 或 boost,则所有 exe 和 dsos 必须使用完全相同的 C++ 运行时版本,并使用相同的构建标志编译(如果您喜欢的话,还必须使用相同版本的 boost ).
我建议在 Visual Studio 上使用警告级别 4,这将很好地列出您的 DSO 界面中的所有上述问题(作为 C4251 警告)
至于你的问题,是的,该函数将 return a 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();
}
但就我个人而言,我建议只 return 使用裸指针,然后在您的 exe 中对其执行 make_unique。这至少消除了 C4251 问题,尽管您可能会被堆问题困扰(除非您将 class 类型的析构函数设为虚拟)
我有一个位于共享对象中的函数,它是用 dlsym
从主程序加载和执行的。
(共享对象和主程序都是C++)
这个函数有没有可能 return 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 有点危险。
- std::unique_ptr 编译器之间存在差异
- std::unique_ptr 不同 C++ 版本
- std::unique_ptr 可能在 debug/release 版本之间有所不同。
这意味着如果您在 DSO 接口中使用 STL 或 boost,则所有 exe 和 dsos 必须使用完全相同的 C++ 运行时版本,并使用相同的构建标志编译(如果您喜欢的话,还必须使用相同版本的 boost ).
我建议在 Visual Studio 上使用警告级别 4,这将很好地列出您的 DSO 界面中的所有上述问题(作为 C4251 警告)
至于你的问题,是的,该函数将 return a 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();
}
但就我个人而言,我建议只 return 使用裸指针,然后在您的 exe 中对其执行 make_unique。这至少消除了 C4251 问题,尽管您可能会被堆问题困扰(除非您将 class 类型的析构函数设为虚拟)