2013-02-09 548 views
1

我正在爲第三方Windows應用程序編寫C++插件DLL。我的插件DLL可以在文件系統中的任何位置生活,並指定從第三方應用程序加載它的位置。Visual C++:插件DLL使用的第三方DLL的位置?

我的DLL的部分功能需要我使用第三方庫(ZeroMQ)。我將我的DLL鏈接到ZeroMQ庫,並且它的構建正確。然而,加載我的DLL在第三方應用程序中,我一直得到一個The specified module could not be found.錯誤。最初,我不清楚我是否使用ZeroMQ靜態庫,如果我還需要zeromq DLL(但顯然它有一個靜態lib包裝訪問DLL:Using .dll in Visual Studio 2010 C++)。

我試着將零mq dll(libzmq-v100-mt-gd-3_2_2.dll放在我的例子中)放在與我的插件DLL相同的文件夾中,但是這並不起作用。

最後通過純粹的實驗,我發現我可以將zeromq dll直接放在與主要第三方應用程序相同的文件夾中,現在我的插件可以工作。不過,理想情況下,我寧願不這樣做。有沒有辦法讓我以某種方式將zeromq dll庫放在與我的插件DLL相同的文件夾中?如果是這樣,怎麼樣?在構建我的DLL時,可能是Visual Studio中的一些配置選項?

+0

是有... – thang 2013-02-09 07:12:27

+0

@thang:德勤。我該怎麼做? – User 2013-02-09 07:17:21

+0

啊,很好的問題,應該早點把進入後:P – thang 2013-02-09 07:20:25

回答

2

你想要做什麼,直到後來用這樣的延遲加載DLL:

http://msdn.microsoft.com/en-us/library/151kt790.aspx

Delay Loading DLLs

http://www.codeproject.com/Articles/9428/Delay-Loading-a-DLL

Prevent .lib from loading DLL at runtime

然後加載之前發生,使用動態加載DLL LoadLibrary允許你輸入dll的整個路徑。

當延遲負載情況,將實現該DLL已經被你LoadLibrary調用,和中提琴加載中...

或者,而不是裝載與調用LoadLibrary,你還可以添加目錄到使用DLL搜索路徑:

http://msdn.microsoft.com/en-us/library/ms686203.aspx

當延遲負載情況,它就會在該目錄中的DLL,和中提琴看...

2

的問題是,搜索路徑贏dows在查找dll包含應用程序的路徑時使用,但不包括插件dll的路徑(除非您可以說服應用程序供應商添加此功能!)。當加載你的插件的DLL時,加載程序會發現它需要從libzmq-v100-mt-gd-3_2_2.dll中導出的函數,並試圖找到它。你發現的是如預期的那樣 - 應用程序目錄位於dll搜索路徑中,所以如果你將libzmq-v100-mt-gd-3_2_2.dll放在那裏,加載器會正確地找到它,並繼續加載你的插件DLL。有很多方法可以將插件的路徑添加到搜索路徑中,但不幸的是,這些不能用於您的dll,因爲只有在dll被正確加載時纔會運行代碼 - 如果libzmq-v100-沒有找到mt-gd-3_2_2.dll!

如上所述,延遲加載可以解決問題。其他的選項,我可以看到的是:

  • 在你的插件安裝程序添加插件PATH環境變量的路徑,並把libzmq-V100-MT-GD-3_2_2.dll在同一地點 - 這方法污染PATH變量,很可能是脆弱的
  • 使用動態鏈接而不是靜態鏈接到libzmq-V100-MT-GD-3_2_2.dll你的插件需要 - 那麼你有過在您加載DLL直接控制使用調用LoadLibrary。該方法的其他優點是,如果你無法找到該庫中的插件需要你可能仍然激活插件,但功能有所降低,或至少提供一個有意義的錯誤/日誌信息。