Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在运行时管理Boost::任意共享库 我正在制作一个C++框架,它应该管理单独构建的自定义模块,这些模块在运行时作为共享库加载。这些模块必须使用自定义数据相互通信,因此我使用一个无序的_映射,其中包含boost::每个模块可以用来设置和读取数据的任何值_C++_Memory Management_Boost_Segmentation Fault_Shared Libraries - Fatal编程技术网

在运行时管理Boost::任意共享库 我正在制作一个C++框架,它应该管理单独构建的自定义模块,这些模块在运行时作为共享库加载。这些模块必须使用自定义数据相互通信,因此我使用一个无序的_映射,其中包含boost::每个模块可以用来设置和读取数据的任何值

在运行时管理Boost::任意共享库 我正在制作一个C++框架,它应该管理单独构建的自定义模块,这些模块在运行时作为共享库加载。这些模块必须使用自定义数据相互通信,因此我使用一个无序的_映射,其中包含boost::每个模块可以用来设置和读取数据的任何值,c++,memory-management,boost,segmentation-fault,shared-libraries,C++,Memory Management,Boost,Segmentation Fault,Shared Libraries,该程序最近开始在关闭时给出一个segfault错误,原因是对象的销毁顺序发生了一个小的变化。经过一些跟踪,我认为我发现了错误:尽管框架保留了保存所有共享数据的无序_映射,但每个boost::any都包含由驻留在共享库中的代码创建的值(必须),因为框架不知道每个键在编译期间将包含哪些值/类型 如果在解除分配映射之前卸载所有共享库,那么boost::any在销毁时会生成一个segfault,因为(我想)包含其值的指针已经从内存中卸载了。如果我先删除映射,然后取消分配所有模块,则不会出现错误。因此,我

该程序最近开始在关闭时给出一个segfault错误,原因是对象的销毁顺序发生了一个小的变化。经过一些跟踪,我认为我发现了错误:尽管框架保留了保存所有共享数据的无序_映射,但每个boost::any都包含由驻留在共享库中的代码创建的值(必须),因为框架不知道每个键在编译期间将包含哪些值/类型


如果在解除分配映射之前卸载所有共享库,那么boost::any在销毁时会生成一个segfault,因为(我想)包含其值的指针已经从内存中卸载了。如果我先删除映射,然后取消分配所有模块,则不会出现错误。因此,我假设当boost::any值被创建和填充时,它的内容会以某种方式分配到与共享库关联的一些内存中,而当共享库关闭时,试图删除boost::any会使所有内容崩溃

std::unordered_map<std::string, boost::any> shared_data;
std::vector<Module> dynamically_loaded_modules;

// RUNTIME DURING SOME MODULE EXECUTION
shared_data["SomeKey"] = my_unknown_typed_data;

// ON PROGRAM EXIT
dynamically_loaded_modules.clear(); // Calls dlclose()
shared_data.clear(); // This crashes
// ---------------
shared_data.clear();
dynamically_loaded_modules.clear(); // This does not crash
std::无序地图共享数据;
std::向量动态加载的模块;
//在某些模块执行期间运行
共享的\u数据[“SomeKey”]=我的\u未知\u类型的\u数据;
//关于程序退出
动态加载的模块。清除();//调用dlclose()
共享_数据。清除();//这个崩溃了
// ---------------
共享_数据。清除();
动态加载的模块。清除();//这不会崩溃
我的问题如下:

  • 我对正在发生的事情的解释现实可行吗?我对dlfcn.h如何管理共享库不太了解
  • 释放地图和模块是否安全?或者我应该有办法让模块显式删除它们创建的每个boost::any吗?我需要这样做吗

您是否收到“访问冲突读取位置\uuuvfptr”的消息? 如果是这样的话,我认为FLOWING的陈述可以解释发生了什么以及为什么。 假设map是在sharedlibrary.dll中创建的,然后在userclient.dll中推送map中的boost::any对象。 any对象存储类型为int的数据。然后创建了一个新的模板类类型boost::any::holder。boost::any::holder析构函数的地址在userclient.dll的地址范围内


好的,现在一切都清楚了,如果卸载userclient.dll,userlcient.dll的地址无效。最后,在SharedLiAry.dll中销毁映射时,应该调用boost::any::holder对象的析构函数,但是boost::any::holder析构函数的地址对于userlicnet.dll无效,并且已经卸载。然后您会看到“访问冲突读取位置\uuu vfptr”的消息。

“它的内容以某种方式被分配到与共享库关联的一些内存上”——可能存在虚拟函数或函数指针。一般来说,最好有销毁顺序镜像构造顺序。加载一些模块,然后创建一个映射。您可以通过向后操作来反转该过程:销毁映射,然后卸载模块。其基本原理是,稍后创建的对象可以很容易地依赖于先前创建的对象,而相反的依赖性则不太可能(尽管只要稍微聪明一点,没有什么是不可能的)。@n.m.模块的代码是通过虚拟函数调用的,因为这是框架能够拥有一个接口来与它一无所知的模块进行对话的唯一方法。@n.m.关于你的第二点,这就是我认为我正在做的:我创建映射,然后加载模块,然后模块完成它们的工作,然后卸载模块,然后销毁映射。但很明显,这是行不通的。。