如何从 dlopen'd 库 L 访问程序 P 中的静态变量?
How can I accessing a static variable in program P from dlopen'd library L?
我有一个库(L),它是由程序(p)使用dlopen动态加载的。L实现了一个插件接口,因此调用它的父接口以获得一些功能。
在p内部是一个单例对象,它动态地创建一个线程池对象a。我需要从L.访问A
然而,因为singleton是通过使用静态变量来工作的,所以当加载L时,它最终会创建自己的实例,在某些情况下这是可以的,但我想要在p中创建的实例。有办法解决这个问题吗?
L中不应该有static
a。让p将a的地址传递给L,即L.init(&A)
。
声明为static
的文件作用域名称具有内部链接。内部链接意味着它们对其他翻译单元是不可见的,即使在没有任何动态库的"经典"链接模型中也是如此。假设静态即使对同一可执行文件中的其他翻译单元也不可见,那么期望它们从附加的动态库中可见是不合理的。
你必须想办法使用外部的、动态的符号来实现必要的联系。也许单例不能有内部名称,而必须有外部名称。
L正在创建自己的对象实例,这不仅是因为对象是静态的,还因为您已经将定义该单例和线程池函数的线程池模块链接到L中。即使是具有外部名称的对象也可能发生这种情况,具体取决于库的链接方式。
您必须选择线程池服务将驻留在其中的单个对象,然后确保它只驻留在其中。你的项目不是有一个实用程序库,你可以在那里坚持这种东西吗?
您可以遵循这样的模型,即它是提供线程池API的程序可执行程序p。这真的是一样的事情。程序P是另一个动态对象,有效地充当线程池模块的库,它将线程池模块提供给自己和其他共享对象。
无论线程池模块位于何处,都要确保没有将该模块的副本静态链接到其他对象:它只位于一个位置。
如果线程池单例的外部名称是该API的一部分(每个人都知道其文档化名称,并直接使用它,将该全局池传递给API函数),则该名称应为外部名称,并在头文件中声明。
如果单例是私有的,那么你必须考虑一些隐藏它的方法,比如让它隐含在函数调用中(只有一个线程池,也就是说),或者在某种程度上抽象对它的访问(提供一个ensure_thread_pool
)函数,该函数在线程池不存在的情况下创建线程池,或者以线程安全的方式返回以前创建的线程池。
思考:为什么stdin
和stdout
没有这个问题?为什么每个库都不实例化自己的stdout
流,并在该流上调用自己的fprintf
函数?为什么,很明显,因为这些东西存在于一个地方:C库。它们的副本不存在于其他地方;其他地方只是通过动态符号引用它们。
- 从终止处理程序访问所有未捕获的异常
- 如何从桌面应用程序访问嵌入式ArangoDB
- 如何从Qt应用程序访问UWP API
- 从测试程序访问共享库中具有静态私有字段的类
- Google Play Games C++API-无法通过程序访问好友
- 如何将功能和数据从一个涡轮C 程序访问到另一个涡轮增压程序
- 通过现有设备驱动程序访问设备
- 从用户应用程序访问环0模式(以及Borland允许这样做的原因)
- 从服务应用程序访问访客帐户系统注册表
- 如何使用FastCGI C/C 应用程序访问POST请求的主体
- 从 C 程序访问 dtrace 探测器
- 从C++程序访问 java 程序当前运行的 javabean
- 多个应用程序访问的单个进程
- 如何从调用程序访问 DLL 的变量?
- C++迭代程序访问下一个元素进行比较
- 从C程序访问C++函数时,收到错误消息"Access violation reading location"
- 如何从作为服务运行的c++程序访问当前登录的用户信息
- 从boost deadline_timer的处理程序访问类数据
- 是否可以同时从Python脚本和C++程序访问GPIO引脚
- 是否可以让两个c++程序访问同一个内存位置