2011-01-22 14 views
3

我正在寫一個(C)程序,其經由的dlopen利用插件系統()determing調用對象。我遇到的絆腳石是主程序導出了一些真正需要知道調用它們的插件的功能(主要是記錄保存,因此插件可以正確卸載,因爲它們添加了像main程序)。使用dlopen工作時()對象

我似乎找不到一個乾淨的方式來做到這一點。我到目前爲止的選項:

  1. 要求插件提供它的名稱,或者我給它加載的一些數據作爲函數的參數。
    • 我不喜歡這樣的選擇,因爲並非所有的功能關心他們是誰從調用,所以它使矛盾和混亂。另外,我想讓插件儘可能難以說明它是誰
  2. 使用backtrace()來確定上一個函數的對象名稱。
    • 這看起來相當難看且不便攜。
  3. 要求插件放置一個包含其名稱的文件級結構體(或其他變量)(我們稱之爲'plugin_info'進行討論)。然後使用dlsym()加載插件來查找變量並通過其名稱對其進行索引(如在散列中)。然後放入#define宏,插件使用這些宏來調用函數,並將宏添加爲&plugin_info作爲參數。
    • 這是我現在使用什麼,但它看起來的hackish。對於一個你必須通過'& plugin_info'的宏傳遞,如果你只是傳遞'plugin_info',那麼它會從主程序中取出'plugin_info',而不是插件。通過地址引用它似乎可以使它編譯成正確的,並且它不會被重定位。這讓我不喜歡這個選項,因爲它看起來像它的未定義的行爲,但它確實有效。當插件開發者遇到函數調用的問題時(通過錯誤的參數類型或什麼),這些宏可能會使它有點混亂。

如果有任何其他想法或技術,我很想很想知道。

+0

+1寫得很好的問題與你要找的是什麼,你已經評估/試了一下選項的詳細解釋和。 – 2011-01-22 13:23:33

回答

2
  1. 你邀請的插件安裝到你的地址空間,因此它可以說謊,覆蓋內存屬於調用者,或者rm -rf ~如果它喜歡。如果這是一個問題,您需要在不使用特權的情況下在單獨的進程中對其進行沙箱處理。
  2. 事實上,這是非常不便攜的。
  3. 這通常是正確的想法,但你已經拙劣並使其變得醜陋。將static添加到plugin_info的定義中,您將擁有完美明確的行爲,而且沒有任何駭人聽聞的行爲。
+0

如果我在其上拋出靜態,則dlsym()無法找到它。除非你說要在主程序的plugin_info中添加靜態(它有一個,因爲被調用的函數是通用的並且需要它),而不是插件的plugin_info。這似乎工作,但我會遇到任何問題與其他插件意外地得到另一個的plugin_info阿夫,因爲他們不是靜態的? – Patrick 2011-01-24 09:28:40