2012-03-13 138 views
0

編輯需要的函數調用:只要有這樣的嘗試:初始化一個DLL

__declspec(dllexport) int foo(int param) 
    {return param*param;} 

和編譯。事實證明,CRT和kernel32的函數仍然被導入。我發現這些來自運行時。問題是爲什麼這個運行時被假定爲需要?我讀過關於搬遷的一些事情。這是一個線索嗎?

我創建了一個提供Win32 GUI小部件的dll。如果我看導入表由MinGW的海灣合作委員會,它看起來像下面生成的DLL(標有(*功能)是那些我叫我自己):

導入表(解釋.idata段內容)

vma:   Hint Time  Forward DLL  First 
       Table Stamp  Chain Name  Thunk 
00006000 00006050 00000000 00000000 00006354 000060d4 

DLL Name: KERNEL32.dll 
vma: Hint/Ord Member-Name Bound-To 
6158  207 DeleteCriticalSection 
6170  236 EnterCriticalSection 
6188  352 FreeLibrary 
6196  510 GetLastError 
61a6  529 GetModuleHandleA (x) 
61ba  577 GetProcAddress 
61cc  734 InitializeCriticalSection 
61e8  814 LeaveCriticalSection 
6200  817 LoadLibraryA 
6210  1173 TlsGetValue 
621e  1213 VirtualProtect 
6230  1215 VirtualQuery 

00006014 00006084 00000000 00000000 00006394 00006108 

DLL Name: msvcrt.dll 
vma: Hint/Ord Member-Name Bound-To 
6240  52 __dllonexit 
624e  182 _errno 
6258  266 _iob 
6260  538 _winmajor 
626c  583 abort 
6274  595 calloc 
627e  610 fflush 
6288  625 free (x) 
6290  633 fwrite 
629a  676 malloc (x) 
62a4  682 memcpy (x) 
62ae  748 vfprintf 

00006028 000060b8 00000000 00000000 000063b8 0000613c 

DLL Name: USER32.dll 
vma: Hint/Ord Member-Name Bound-To 
62ba  134 DefWindowProcA (x) 
62cc  342 GetWindowLongA (x) 
62de  405 LoadCursorA  (x) 
62ec  480 RegisterClassExA (x) 
6300  508 SendMessageA  (x) 
6310  569 SetWindowLongA (x) 

在我實際上可以使用DLL之前,似乎有很多事情要做。例如,我從未在我的代碼中使用過fwrite,但它在導入表中顯示。這表示它在編譯器在鏈接時添加的某些初始化例程中使用。 爲什麼? (x)標記的函數不應該足夠嗎?

+0

看起來您的DLL的代碼很小且很簡單。也許你可以發佈完整的代碼或其他測試代碼,它有相同的問題? – Oleg 2012-06-05 16:48:39

回答

1

C代碼運行啓動代碼。關於這意味着什麼底漆,讀取例如在谷歌的第一個鏈接約"C startup code"

簡而言之:它建立了堆,棧和初始化靜態變量,用的東西,如「環境」一起,爲內存傳遞給程序的參數,內部語言環境等等。什麼究竟是取決於操作系統,編譯器和各自的版本。

由於啓動代碼初始化線程本地存儲以及什麼,所以依賴關係確實被鏈接了。您可以通過在與gcc鏈接時添加-nodefaultlibs來防止此問題(至少部分),但要注意:Dragons Ahead!

+0

但是,主應用程序不應該完成大部分工作嗎?如果dll不使用TLS,CRT和其他東西,用-nodefaultlibs安全嗎? – user877329 2012-06-08 13:15:13

+1

'-nodefaultlibs'僅省略系統庫(基本OS功能所需)。如果你不知道你在做什麼,''nostartfiles'會讓你陷入麻煩。 – rubenvb 2012-06-08 14:18:15

1

我創建了一個提供Win32 GUI小部件的dll。

這就足夠了,你不能在不使用Win32 API函數的情況下編寫Win32小部件。這是您的導入錶轉儲顯示的內容。你總是會依賴核心Windows API kernel32.dll。當您對Windows執行任何操作時,您將獲得對user32.dll的依賴。 msvcrt.dll依賴關係由mingw生成,它鏈接Microsoft C運行時庫的動態版本。

一切都正常,Windows加載程序確保這些DLL在您啓動程序時加載和鏈接。

+0

這是真的,但它不回答我的問題 – user877329 2012-03-16 10:12:58

+0

我做了,編輯回滾。 – 2012-03-16 11:48:53

+0

不,你沒有,因爲我知道我問了什麼?問題是A:爲什麼導入表中有更多的**函數**比我所稱的要多。我認爲他們來自初始化例程。這會導致問題B:如果我唯一想要的是dll中的代碼工作,那麼初始化**具有多少**。我不應該需要_italic_ fwrite或者我? – user877329 2012-03-17 09:48:40