2011-12-17 20 views
1

聯我創建支持在運行時動態地加載的DLL形式模塊的應用的應用。該代碼以下述方式被佈置:鏈接DLL以靜態庫並將其加載到針對相同的靜態庫

  • - 靜態庫

    這具有一種機制來加載共享庫和調用返回一個新的模塊對象「創建」功能(用途一個共享標題)。

  • 模塊共享庫(針對核心靜態庫鏈接)

    該模塊使用共享模塊頭,並且還從核心庫(因此爲什麼它被抵靠芯庫鏈接)使用其他類。它被構建爲包含來自靜態庫的所有符號。

  • 測試應用可執行文件(與核心靜態庫鏈接)

我越來越時髦,和看似零星的行爲。他們總是結束在訪問衝突,但似乎我很明確設置(整數),其成員變量將在後面的功能,打印出的垃圾(我已經證實,他們沒有被更早刪除)。這隻曾經似乎如果他們的動態庫加載發生(即使我從來沒有調用創建功能)。

我的主要問題是,共享庫中的符號是否會與可執行文件中的符號發生衝突(因爲它們來自同一靜態庫),並且即使它們完全相同也會導致問題靜態庫?

+0

你在什麼操作系統上? – Laserallan 2011-12-17 19:17:53

+0

我目前在OS X上看到這一點,但它也編譯在Linux(Ubuntu)和Windows上。現在我將在Linux上嘗試此操作以查看是否發生了相同的事情。 – drewag 2011-12-17 19:24:56

+0

嘗試在valgrind下運行您的程序以更好地診斷它。 – 2011-12-17 20:02:26

回答

5

我不能爲Linux和OS X的行爲說話,但在Windows上,下面是到底發生了什麼。既然你說你也想在Windows上編譯,這是相關的。

您遇到的問題是您實際上擁有核心中的所有內容的多個版本。每個模塊和應用程序本身有自己的核心副本,其變量共享。這包括C運行時,所以像新/刪除跨模塊邊界是充滿了危險。

爲了驗證這是正在發生的事情,創建一個簡單的測試:設置在覈心一個全球性的以在您的測試應用程序中的值,然後從從動態加載代碼嘗試訪問全球,看看你得到。我會打賭你會發現你的商店不會被反映出來!

解決方案:

1)使芯部的共享動態庫。這可能或可能不是您的選擇。

2)仔細操作上述知識;所有的CRT和/或你自己的核心狀態都不會被共享,所以你必須確保事物在模塊邊界的各個方面被分配/銷燬。

我自己的應用程序的設計幾乎與您的應用程序完全相同;即應用程序和模塊都需要共享代碼的靜態庫,然後動態加載由應用程序內核加載的插件。

我對所有必須跨模塊訪問的共享核心狀態所做的工作是,每個模塊在加載後執行的第一件事情是將其「核心指針」設置爲應用程序中核心庫的實例化。這確保所有模塊都使用相同的數據。