文章編號: 189133 - 上次校閱: 2006年8月14日 - 版次: 4.1

如何使用型別程式庫讓 C DLL 更輕鬆存取 VB

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

因為這是 Visual Basic 的第一個版次,因此提供了 Declare 陳述式做為利用以其他語言撰寫之 DLL 函數的方式,如 C。但是 Declare 陳述式並不完美,同時您也必須對 DLL 有相當程度的熟悉 (如同您熟悉 Visual Basic 程式碼的程度一般)。型別程式庫在呼叫匯出的 C 函數方面可提供更友善的方式來使用 Visual Basic。

本文將告訴您如何在建置 DLL 時建立型別程式庫,以及如何從 Visual Basic 參照該程式庫。

其他相關資訊

型別程式庫是在自動化中使用的複合文件檔案 (.tlb 檔)。型別程式庫包含自動化伺服器向其用戶端公開的類別、物件、模組及介面的重要資訊。好處是,伺服器不需要具備自動化支援特性就可利用型別程式庫。事實上,大部分的 C DLL 都不是自動化伺服器,它們只需將其函數宣告為型別程式庫中模組的成員。這樣自動化用戶端 (如 Visual Basic) 就可讀取並繫結此資訊,就如同它處理任何物件一樣。因為 Visual Basic 可以完成所有的工作,因此不需要 Declare 陳述式或花費精力來記住常數。

為 DLL 建立型別程式庫有許多優點。最重要的是它可以增強型別的安全性。同時您也會獲得更好的效能,因為 Visual Basic 會使用之前的繫結自動繫結到您的函數。相反的,所有 Declare 陳述式都是晚期繫結。此外,您還可以更好地控制將 DLL 提供給Visual Basic 程式設計人員的方式。型別程式庫可讓您為函數及參數提供 Visual Basic 易記名稱,還有列舉及使用者定義型別 (UDT) 等其他有用內容。

目前來說,型別程式庫是使用以介面定義語言 (IDL) 或物件描述語言 (ODL) 撰寫的指令碼來建立的。然後會使用隨附於 Visual Studio 的 MkTypLib.EXE 或 MIDL.EXE 來編譯這些指令碼。Visual C++ 會分擔一些建立型別程式庫的工作,因為在您編譯專案時,與 DLL 專案關聯的任何 ODL 檔案都將自動使用 MIDL 進行編譯。

逐步範例 - 建立 DLL 及型別程式庫

  1. 開啟 Visual C++ 5.0 並選取 [檔案|新增]。在 [專案] 索引標籤中選取 [Win32 動態連結程式庫] 並將專案命名為 "TLBSamp"。
  2. 再次選取 [檔案|新增]。在 [檔案] 索引標籤中,選取 [C++ 原始程式檔]、將檔案命名為 "TLBSamp.c",再按一下 [確定]。
  3. 再次重複步驟 2,並在這一次選取 [文字檔案] 做為檔案類型。分別將檔案命名為 "TLBSamp.def" 及 "TLBSamp.odl"。
  4. 接下來,將下列程式碼加入 TLBSamp.c:
          #include <windows.h>
    
          // MyDll_ReverseString -- Reverses the characters of a given string
          void __stdcall MyDll_ReverseString(LPSTR lpString)
          {
             _strrev(lpString);
          }
    
          // MyDLL_Rotate -- Returns bit rotation of 32-bit integer value
          int __stdcall MyDll_Rotate(int nVal, int nDirect, short iNumBits)
          {
             int nRet = 0;
    
             if((iNumBits < 1) || (iNumBits > 31))
                return nRet;
    
             switch(nDirect)
             {
             case 0:
                // Rotate nVal left by iNumBits
                nRet = (((nVal) << (iNumBits)) |
                        ((nVal) >> (32-(iNumBits))));
                break;
             case 1:
                // Rotate nVal right by iNumBits
                nRet = (((nVal) >> (iNumBits)) |
                        ((nVal) << (32-(iNumBits))));
                break;
             }
    
             return nRet;
          }
    
    						
  5. 如果要讓函數可匯出,將下列程式碼加入 TLBSamp.def:
          LIBRARY TLBSamp
          DESCRIPTION 'Microsoft KB Sample DLL'
          EXPORTS
            MyDll_ReverseString
            MyDll_Rotate
    
    						
  6. 新增下列程式碼到 TLBSamp.odl 從而在型別程式庫中宣告函數:
          // This is the type library for TLBSamp.dll
          [
          // Use GUIDGEN.EXE to create the UUID that uniquely identifies
          // this library on the user's system. NOTE: This must be done!!
             uuid(F1B9E420-F306-11d1-996A-92FF02C40D32),
          // This helpstring defines how the library will appear in the
          // References dialog of VB.
             helpstring("KB Sample: Make your C DLL More Accessible"),
          // Assume standard English locale.
             lcid(0x0409),
          // Assign a version number to keep track of changes.
             version(1.0)
          ]
          library TLBSample
          {
    
          // Define an Enumeration to use in one of our functions.
          typedef enum tagRotateDirection
          {
             tlbRotateLeft=0,
             tlbRotateRight=1
          }RotateDirection;
    
          // Now define the module that will "declare" your C functions.
          [
             helpstring("Sample functions exported by TLibSamp.dll"),
             version(1.0),
          // Give the name of your DLL here.
             dllname("TLBSamp.dll")
          ]
          module MyDllFunctions
          {
    
             [
             // Add a description for your function that the developer can
             // read in the VB Object Browser.
                helpstring("Returns the reverse of a given string."),
             // Specify the actual DLL entry point for the function. Notice
             // the entry field is like the Alias keyword in a VB Declare
             // statement -- it allows you to specify a more friendly name
             // for your exported functions.
                entry("MyDll_ReverseString")
             ]
             // The [in], [out], and [in, out] keywords tell the Automation
             // client which direction parameters need to be passed. Some
             // calls can be optimized if a function only needs a parameter
             // to be passed one-way.
             void __stdcall ReverseString([in, out] LPSTR sMyString);
    
             [
                helpstring("Rotates a Long value in the given direction."),
                entry("MyDll_Rotate")
             ]
             // Besides specifying more friendly names, you can specify a more
             // friendly type for a parameter. Notice the Direction parameter
             // has been declared with our enumeration. This gives the VB
             // developer easy access to our constant values.
             int __stdcall BitRotate([in] int Value,
                                     [in] RotateDirection Direction,
                                     [in] short Bits);
    
          } // End of Module
          }; // End of Library
    
    						
  7. 透過選擇 [建置] 功能表的 [全部重建] 來編譯 DLL 及型別程式庫。完成時,將新的 DLL (TLBSamp.dll) 複製到您的 Visual Basic 目錄,進行測試。
注意:為方便起見,您可能希望將型別程式庫作為資源包括到 DLL 中。這樣就可以不需要向 Visual Basic 程式開發人員分散單獨的 TLB 檔案。

如果要將程式庫加入做為資源,請完成下列步驟:
  1. 選取 [檔案|新增]。在 [檔案] 索引標籤中,選取 [文字檔案]、將檔案命名為 "TLBSamp.rc",再按一下 [確定]。
  2. 在出現的文字視窗中新增下行:

    1 typelib TLBSamp.tlb
  3. 儲存檔案並重新編譯 DLL。完成時,將新的 DLL (TLBSamp.dll) 複製到您的 Visual Basic 目錄,進行測試:如果出現提示,請覆寫前一個檔案。

逐步範例 - Visual Basic 測試應用程式

  1. 如果要測試您的 DLL 及型別程式庫,請開啟 Visual Basic 5.0 並建立新的標準專案。根據預設會建立 Form1。
  2. 選取 [專案] 功能表中的 [參考] 來呼叫 [參考] 對話方塊,然後按一下 [瀏覽] 尋找新的型別程式庫 (或 DLL,如果您已將程式庫加入為資源)。找到之後按一下 [確定]。Visual Basic 將在您首次參考程式庫時自動登錄程式庫。請確定您已在參考清單中勾選您的程式庫 (「KB 範例:讓 C DLL 更容易存取」),然後關閉對話方塊。
  3. 按下 F2 鍵以開? [物件瀏覽器]。請注意您的程式庫 (TLBSamp) 已加入 Visual Basic 專案中,且可以呼叫原始 Visual Basic 函數的方式來呼叫您的函數。Visual Basic 甚至可以在開發人員向 BitRotate 函數中輸入 Direction 參數時下拉列舉清單。
  4. 將 CommandButton 加入至 Form1,然後將下列程式碼加入按鈕的 Click 事件:
          Private Sub Command1_Click()
             Dim n1 As Long, n2 As Long, nTmp As Long
             Dim sTest As String, sMsg As String
    
             sTest = "Hello World!"
             n1 = 100
    
             ReverseString sTest
               sMsg = sTest & " | "
             ReverseString sTest
               sMsg = sMsg & sTest & vbCrLf
    
             nTmp = BitRotate(n1, tlbRotateLeft, 2)
             n2 = BitRotate(nTmp, tlbRotateRight, 2)
               sMsg = sMsg & Str$(n1) & " : " & Str$(nTmp) & " : " & Str$(n2)
    
             MsgBox sMsg
          End Sub
    
    						
  5. 現在按下 F5 鍵就可以在 IDE 中執行 vb5allB 專案。

    注意:如果您收到錯誤訊息,可能是因為 Visual Basic 找不到您的 DLL。請確定在執行應用程式之前,您已將 DLL 複製到 Visual Basic 目錄或系統路徑。

?考

如需 ODL 或 IDL 結構的詳細資訊,請參閱下列 Microsoft Developer Network (MSDN) 資料庫中的文章:
標題:型別程式庫及物件描述語言
標題:介面定義及型別程式庫

如需詳細資訊,請參閱「Microsoft 知識庫」中的下列文件:
143258? (http://support.microsoft.com/kb/143258/ ) How To Create Constants and DLL Declarations in a Type Library

122285? (http://support.microsoft.com/kb/122285/ ) : How To Add Type Libraries as Resources to .dll and .exe Files

142840? (http://support.microsoft.com/kb/142840/ ) INFO: Visual Basic Requirements for Exported DLL Functions

(c) Microsoft Corporation 1998. All Rights Reserved.由 Microsoft Corporation,Richard R. Taylor 提供。

這篇文章中的資訊適用於:
  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
關鍵字:?
kbhowto KB189133
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。