在模块之间共享内存 [英] Sharing memory between modules

查看:107
本文介绍了在模块之间共享内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何在不同的程序模块之间共享一些内存-比方说,我有一个主应用程序(exe),然后有一个模块(dll).它们都链接到同一个静态库.该静态库将具有一些提供各种服务的管理器.我要实现的是让该管理器在所有应用程序模块之间共享,并在库初始化期间透明地执行此操作. 在进程之间,我可以使用共享内存,但是我只希望在当前进程中共享它. 您能想到一些跨平台的方法吗?如果它们提供了一些便利,可以使用boost库.

I was wondering how to share some memory between different program modules - lets say, I have a main application (exe), and then some module (dll). They both link to the same static library. This static library will have some manager, that provides various services. What I would like to achieve, is to have this manager shared between all application modules, and to do this transparently during the library initialization. Between processes I could use shared memory, but I want this to be shared in the current process only. Could you think of some cross-platform way to do this? Possibly using boost libraries, if they provide some facilities to do this.

我现在唯一想到的解决方案是使用各个操作系统的共享库,所有其他模块都将在运行时链接到该库,并将管理器保存在该库中.

Only solution I can think of right now, is to use shared library of the respective OS, that all other modules will link to at runtime, and have the manager saved there.

弄清我的实际需求:

  1. 我需要找出共享管理器是否已经创建(以下答案已经提供了一些方法)
  2. 获取指向管理器的指针(如果存在),或将指针设置到新创建的管理器对象的某个位置.

推荐答案

我认为您需要共享库的帮助才能以任何可移植的方式进行此操作.不必知道有关模块之间共享的对象的任何信息,它只需要提供从键(可能是字符串)到指针的一些全局可访问的映射.

I think you're going to need assistance from a shared library to do this in any portable fashion. It doesn't necessarily need to know anything about the objects being shared between modules, it just needs to provide some globally-accessible mapping from a key (probably a string) to a pointer.

但是,如果您愿意调用OS API,这是可行的,并且我认为您可能只需要OS特定部分的两种实现(一个用于Windows DLL和GetProcAddress,一个用于使用dlopen的OS).

However, if you're willing to call OS APIs, this is feasible, and I think you may only need two implementations of the OS-specific part (one for Windows DLLs and GetProcAddress, one for OSes which use dlopen).

在加载每个模块时,它将遍历先前加载的模块的列表,以查找导出特殊功能的模块.如果找到一个(没关系,那无关紧要,因为不变的是所有已完全加载的模块都知道该公共对象),则它从先前加载的模块中获取该公共对象的地址,然后增加引用计数.如果找不到,它将分配新数据并初始化引用计数.在模块卸载期间,如果引用计数达到零,它将减少引用计数并释放公共对象.

As each module loads, it walks the list of previously loaded modules looking for any that export a specially-named function. If it finds one (any, doesn't matter which, because the invariant is that all fully-loaded modules are aware of the common object), it gets the address of the common object from the previously loaded module, then increments the reference count. If it's unable to find any, it allocates new data and initializes the reference count. During module unload, it decrements the reference count and frees the common object if the reference count reached zero.

当然,必须对公共对象使用OS分配器,因为尽管不太可能,但是它可能是从与第一次加载它的库不同的库中释放出来的.这也意味着公共对象不能包含任何虚拟函数或指向不同模块段的任何其他种类的指针.必须使用OS进程范围的分配器动态分配其所有资源.对于以libc ++为共享库的系统来说,这可能减轻了负担,但您说的是静态链接CRT.

Of course it's necessary to use the OS allocator for the common object, because although unlikely, it's possible that it is deallocated from a different library from the one which first loaded it. This also implies that the common object cannot contain any virtual functions or any other sort of pointer to segments of the different modules. All its resources must by dynamically allocated using the OS process-wide allocator. This is probably less of a burden on systems where libc++ is a shared library, but you said you're statically linking the CRT.

Win32中所需的功能包括EnumProcessModulesGetProcAddressHeapAllocHeapFreeGetProcessHeapGetCurrentProcess.

Functions needed in Win32 would include EnumProcessModules, GetProcAddress, HeapAlloc, and HeapFree, GetProcessHeap and GetCurrentProcess.

所有考虑因素,我想我都会坚持将公共对象放在其自己的共享库中,该共享库利用加载程序的数据结构来查找它.否则,您将重新发明装载程序.即使将CRT静态链接到多个模块中也可以使用,但我认为您正在为违反ODR做好准备.真正要保留公用数据POD.

Everything considered, I think I would stick to putting the common object in its own shared library, which leverages the loader's data structures to find it. Otherwise you're re-inventing the loader. This will work even when the CRT is statically linked into several modules, but I think you're setting yourself up for ODR violations. Be really particular about keeping the common data POD.

这篇关于在模块之间共享内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆