簡體   English   中英

如何從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.

然而,因為單例通過使用靜態變量工作,當加載L時它最終會創建它自己的實例,這在某些情況下可以正常但我想要在P中創建的實例。有沒有辦法解決這個問題?

你不應該在L中有static A.讓P將A的地址傳遞給L,即L.init(&A)

聲明為static文件范圍名稱具有內部鏈接。 內部鏈接意味着它們對其他翻譯單元是不可見的,即使在沒有任何動態庫的“經典”鏈接模型中也是如此。 鑒於即使對於同一可執行文件中的其他翻譯單元也不可見靜態,期望它們從附加的動態庫中可見是不合理的。

您必須考慮使用外部動態符號實現必要鏈接的方法。 也許單身人士根本不能擁有內部名稱,但必須有外部名稱。

L正在創建自己的對象實例,不僅因為該對象是靜態的,而且因為您已將鏈接到L的線程池模塊定義了該單例和線程池函數。 即使對象具有外部名稱,也會發生這種情況,具體取決於庫的鏈接方式。

您必須選擇線程池服務所在的單個對象,然后確保它只駐留在那里。 你的項目是不是有一個實用程序庫,你可以堅持這種事情?

可以遵循提供線程池API的程序可執行文件P的模型。 這真是一回事。 程序P是另一個動態對象,有效地充當線程池模塊的庫,它提供給自己和其他共享對象。

無論該線程池模塊的位置如何,請確保您沒有將該模塊的副本靜態鏈接到其他對象:它只存在於一個位置。

如果線程池單例的外部名稱是該API的一部分(每個人都知道它的文檔名稱並直接使用它,將該全局池傳遞給API函數)那么該名稱應該是外部的,並在頭文件中聲明。

如果單例是私有的,那么你必須考慮一些隱藏它的方法,比如在函數調用中隱含它(只有一個線程池,就是這樣)或者在某種程度上抽象訪問它(提供一個ensure_thread_pool )函數,如果一個線程池不存在,它將創建一個線程池,或者以線程安全的方式返回先前創建的線程池。

想一想:為什么不這樣做,例如stdinstdout有這個問題? 為什么不是每個庫都實例化自己的stdout流並在該流上調用自己的fprintf函數? 顯然,為什么這些東西生活在一個地方:C庫。 他們的副本不住在其他地方; 其他地方只需通過動態符號引用它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM