2009-08-10 40 views
3

我試圖顯式鏈接一個DLL。沒有其他資源可用,除了DLL文件本身以及關於類及其成員函數的一些文檔。顯式加載DLL

從文檔,每一個類都有自己

  1. 構件的typedef
    例如:typedef std::map<std::string,std::string> Server::KeyValueMap, typedef std::vector<std::string> Server::String Array
  2. 構件枚舉
    例如:enum Server::Role {NONE,HIGH,LOW}
  3. 成員函數
    例如:void Server::connect(const StringArray,const KeyValueMap), void Server::disconnect()

實現從谷歌的搜索代碼,我管理加載DLL可以調用斷開功能..

dir.h

LPCSTR disconnect = "[email protected]"; 
LPCSTR connect = 
"[email protected]"; 

從我得到的Depends.exe上面的函數名。這是所謂的C++中的裝飾/損壞的函數名稱?

的main.cpp

#include <iostream> 
#include <windows.h> 
#include <tchar.h> 
#include "dir.h" 

typedef void (*pdisconnect)(); 

int main() 
{ 
    HMODULE DLL = LoadLibrary(_T("server.dll")); 
    pdisconnect _pdisconnect;` 

    if(DLL) 
    { 
     std::cout<< "DLL loaded!" << std::endl; 
     _disconnect = (pdisconnect)GetProcAddress(DLL,disconnect); 


     if(_disconnect) 
     { 
      std::cout << "Successful link to function in DLL!" << std::endl; 
     } 

     else 
     { 
      std::cout<< "Unable to link to function in DLL!" << std::endl; 
     } 
    } 
    else  
{ 
std::cout<< "DLL failed to load!" << std::endl; 
} 
FreeLibrary (DLL); 
return 0;} 

下如何調用(比如)連接其在DLL本身聲明的參數的數據類型的成員函數?

編輯

更多信息:

  • 的DLL來使用Java示例實現。 Java示例包含使用SWIG和源代碼生成的Java包裝器。
  • 該文檔列出了所有類,它們的成員函數以及它們的數據類型。根據該文檔,從C++源代碼生成的列表。(??)
  • 沒有其他的信息給予(在使用什麼編譯器生成的DLL沒有資料)

我的同事是實施使用Java的接口基於給出的Java示例,而我被要求使用C++實現。該DLL來自第三方公司。

我會問他們關於編譯器。我應該從他們那裏得到任何其他信息?

我有一個關於JNI的快速閱讀,但我不明白它在這種情況下如何實現。

更新

我有點糊塗了......(好吧,好吧......很迷茫)

  1. 我是否分別致電(GetProcAddress的)每個公共成員函數,只有當我想用它們?
  2. 我是否創建了一個模擬類在dll中的類。然後在類定義裏面,我調用DLL的等價函數? (我在這裏有意義嗎?)fnieto,這是你在帖子末尾給我看的東西嗎?
  3. 是否有可能從DLL實例化整個類?

我試圖使用我的第一篇文章中描述的連接功能。從DLL了Depends.exe輸出,

  • 的std ::地圖// KeyValueMap具有以下成員函數:德爾,空,獲取,has_1key,設置
  • 的std ::矢量//字符串數組有下面的成員函數:添加,能力,清晰,獲取,爲IsEmpty,儲備,設置,大小

這是從地圖和矢量的成員函數的不同之處我的編譯r(VS 2005)...

任何想法?或者我在這裏得到錯誤的圖片...

回答

3

除非您使用反彙編程序並嘗試從彙編代碼中找出參數類型,否則您不能。這些類型的信息不會存儲在DLL中,而是存儲在隨DLL一起提供的頭文件中。如果你沒有它,這個DLL可能不會被你使用。

0

如果我是你的話,我會非常小心:STL庫不是被設計用於跨越編譯邊界的。

不是說它不能完成,但你需要知道你正在進入什麼。

這意味着只有在使用相同的編譯器和版本以及與原始DLL相同的設置(特別是DEBUG vs. RELEASE)編譯EXE時,跨DLL邊界使用STL類才能安全地工作。我的意思是「精確」匹配。

C++標準STL庫是行爲規範,而不是實現規範。不同的編譯器甚至同一編譯器的不同修訂版可能會在代碼和數據實現方面有所不同。當你的庫返回給你一個std::map時,它會讓你回到與DLL的STL版本一起工作的位,而不一定是在EXE中編譯的STL代碼。

(我甚至不接觸的事實,名字改編也可以從編譯器而有所不同)

沒有你的情況更多的細節,我不能肯定;但這可能是一堆蠕蟲。

+0

感謝您的回覆......您還需要什麼其他細節?..我不確定我應該在尋找什麼細節.. – justin 2009-08-11 01:26:34

+0

好吧 - 從本質上說,DLL是從哪裏來的。如果你說這是一個傳給你的DLL,並且你不知道它來自哪裏,或者使用了什麼編譯器,我會非常擔心。如果它是由組織中的其他人開發的,並且您確切知道他們正在使用哪種編譯器,並且可以與其他人協調您的編譯器升級,那麼我將不那麼擔心。就像@fnieto一樣,我沒有注意到Java Native Interface連接;我沒有使用JNI的經驗。 – 2009-08-11 04:10:53

0

爲了與DLL鏈接,您需要:

  1. 導入庫(.LIB文件),這說明C/C++的名字和DLL出口之間的關係。
  2. 導出項目(通常是函數)的C/C++簽名,描述了調用約定,參數和返回值。這通常出現在頭文件(.H)中。

從你的問題看起來你可以猜到簽名(#2),但你真的需要LIB文件(#1)。

鏈接器可以幫助您使用中間DEF從DLL生成LIB。 請參閱此問題以獲取更多詳細信息:How to generate an import library from a DLL?

然後,您需要將.lib作爲「附加庫」傳遞給鏈接器。該DLL必須在PATH或目標文件夾中可用。