首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

Win32 組合語言教程:動態連結庫(DLL)建立與呼叫完整指南

     編輯:組合語言

前言

動態連結庫(DLL)是 Windows 模組化程式設計的基石,允許多程式共享同一程式碼拷貝於記憶體中,節省資源並利於維護。本文涵蓋 DLL 架構原理、匯入庫機制、LoadLibrary/GetProcAddress 動態載入技術,並提供 MASM 建立 DLL 與呼叫 DLL 的完整範例框架。

靜態連結 vs 動態連結

  • 靜態連結:連結器將庫函式機器碼複製進可執行檔,每程式一份拷貝,浪費磁碟與記憶體。
  • 動態連結:執行時由載入器將 DLL 映射進程序位址空間,全系統僅一份程式碼拷貝(透過分頁共享),各程式擁有獨立資料段。

DLL 載入流程與匯入庫

  1. 編譯/連結應用程式時,連結器從匯入庫(.lib)提取符號資訊寫入 PE 匯入表。
  2. 載入器讀取匯入表,定位 DLL 檔案,映射至進程空間,修正函式呼叫位址。
  3. 若缺少匯入庫,可改用 LoadLibrary + GetProcAddress 手動載入並取得函式位址(執行期連結)。

匯入庫僅含符號與重定位資訊,不含實際程式碼;靜態庫則含完整機器碼。

DLL 專案結構(MASM)

原始碼架構

; DLLSkeleton.asm
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
.code

DllEntry proc hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD
  mov eax, TRUE
  ret
DllEntry Endp

TestFunction proc
  ret
TestFunction endp

End DllEntry

模組定義檔

; DLLSkeleton.def
LIBRARY DLLSkeleton
EXPORTS TestFunction

連結命令

link /DLL /SUBSYSTEM:WINDOWS /DEF:DLLSkeleton.def /LIBPATH:c:\masm32\lib DLLSkeleton.obj

產出 DLLSkeleton.dll 與 DLLSkeleton.lib(匯入庫)。

DLL 進入點參數詳解

DllEntry proc hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD
  • hInstDLL:DLL 模組控制碼(非進程實例控制碼),難以事後取得,建議自行保存。
  • reason 四種值:
    • DLL_PROCESS_ATTACH:首次載入,執行初始化
    • DLL_PROCESS_DETACH:卸載,釋放資源
    • DLL_THREAD_ATTACH:新執行緒建立
    • DLL_THREAD_DETACH:執行緒結束
  • 返回 TRUE 允許載入繼續,FALSE 導致載入失敗。

執行期動態載入:LoadLibrary / GetProcAddress / FreeLibrary

適用於無匯入庫、需條件載入、或呼叫未文件化函式的情境。

; UseDLL.asm
invoke LoadLibrary, addr LibName          ; LibName = "DLLSkeleton.dll"
.if eax==NULL
  ; 載入失敗處理
.else
  mov hLib, eax
  invoke GetProcAddress, hLib, addr FunctionName  ; FunctionName = "TestHello"
  .if eax==NULL
    ; 函式不存在
  .else
    mov TestHelloAddr, eax
    call [TestHelloAddr]                     ; 間接呼叫
  .endif
  invoke FreeLibrary, hLib                   ; 釋放 DLL
.endif
  • LoadLibrary:成功返回模組控制碼,失敗 NULL。系統維護參考計數,重複載入同一 DLL 僅增加計數。
  • GetProcAddress:在 DLL 匯出表查找函式名稱,返回入口位址。位址在 DLL 未卸載前固定,可緩存。
  • FreeLibrary:遞減參考計數,歸零時真正卸載。

進階議題

  • 名稱修飾:C/C++ 函式需 extern "C" 避免修飾;MASM PROC 預設不修飾。
  • 執行緒區域儲存 (TLS):DLL 可使用 TLS 為每執行緒提供獨立資料。
  • DLL 地獄:版本衝突風險,現代 Windows 採 Side-by-Side 組件技術緩解。

總結

DLL 是 Windows 程式設計的核心重用機制。掌握匯入庫靜態連結與 LoadLibrary 動態載入兩種模式,理解 DllEntry 生命週期通知、匯出表定義、連結器選項,即可靈活構建模組化應用系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved