2017-06-06 72 views
0

有沒有辦法從運行時加載的DLL加載所有函數?當前代碼:加載全部DLL函數

hGetProcIDDLL = LoadLibrary(dll); 

typedef int(*f_connection_a)(args); 
typedef int(*f_connection_b)(args); 
typedef int(*f_connection_c)(args); 

f_connection_a connection_a = (f_connection_a)GetProcAddress(hGetProcIDDLL, "connection_a"); 
f_connection_b connection_b = (f_connection_b)GetProcAddress(hGetProcIDDLL, "connection_b"); 
f_connection_c connection_c = (f_connection_c)GetProcAddress(hGetProcIDDLL, "connection_c"); 

正如你所看到的,這很快變得繁瑣,你必須像這樣定義的每個DLL函數。有沒有辦法加載所有DLL函數,而不必列出它們?

+0

而且,您打算如何調用這些函數,而不用調用'GetProcAddress'來獲取某個函數的入口點地址?另外,在這裏你不是_loading_函數。整個.dll被LoadLibrary調用加載,所以當它返回時 - 所有的函數都已經被加載了。 –

+0

我在詢問是否有辦法讓這個過程自動化。 – ViliX64

+0

您可以導出一個函數,該函數返回指向該庫中所有其他函數的指針數組。 – VTT

回答

2

因爲這裏「connection_ *」只是一個變量,除了運行一個代碼,比如調用一個函數來獲取一個函數的地址之外,沒有辦法對它們進行初始化。 WinAPI在運行時沒有綁定函數的批量方法。這是WinAPI的限制。這種方法的目的是單獨檢查函數的存在,並將庫加載延遲到實際需要的時間點(或者如果未使用,則完全避免加載)。

但是,您可以通過使用導入表功能在程序加載階段綁定DLL來避免這種混亂的代碼。在這種情況下,Windows會將可執行映像加載到內存中,然後加載所有依賴的DLL,並在啓動可執行代碼之前自動綁定導入的函數。爲此,您需要:

  1. 爲您需要加載的庫準備* .def文件。最簡單的方法是在dll文件上啓動「impdef.exe my.dll」命令。您可能會發現微小的impdef.exe不需要安裝在TinyC軟件包中(請參閱https://bellard.org/tcc/)。
  2. 然後通過啓動「LIB /def:my.def /out:my.lib
  3. 與您的項目爲常規庫,鏈接庫生產準備後對應的*的.lib文件。

此方法的缺點是,如果DLL不存在或損壞,則可執行文件根本無法啓動。但這是便利導入功能的小額支付。