国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
如何寫 C dll 和調(diào)用它們從 Visual Basic


本文概括介紹了如何使用 Visual basic 的 dll。它包括以下問題: 部分 1.0 什么是 DLL?1.1 為什么使用 DLL?1.2 DLL 的構(gòu)成...

本文概括介紹了如何使用 Visual basic 的 dll。它包括以下問題:

部分

  • 1.0 什么是 DLL?
  • 1.1 為什么使用 DLL?
  • 1.2 DLL 的構(gòu)成。
  • 1.3 DLL 內(nèi)存管理問題。
  • 1.4 構(gòu)建使用 Visual c + + DLL。
  • 1.5 示例 C DLL。

部分 B

  • 2.0 從 Visual Basic 中調(diào)用的 dll。
  • 2.1 DLL 參數(shù)。
  • 2.2 故障排除。
  • 2.3 示例 Visual Basic 電話程序。

更多信息
部分 A 1.0 什么是 DLL? dll (動態(tài)鏈接庫) 是 Windows 的一個重要方面。DLL 包含可執(zhí)行程序可以在執(zhí)行過程中調(diào)用的函數(shù)。 也就 DLL...

部分 A

1.0 什么是 DLL?

dll (動態(tài)鏈接庫) 是 Windows 的一個重要方面。DLL 包含可執(zhí)行程序可以在執(zhí)行過程中調(diào)用的函數(shù)。 也就 DLL 是一種庫的程序可以動態(tài)地鏈接使用的函數(shù)。

鏈接可以是靜態(tài)或動態(tài)。靜態(tài)鏈接不會更改。您的程序訪問庫函數(shù)時所需的 所有地址信息被都固定的可執(zhí)行文件在創(chuàng)建和執(zhí)行過程中保持不變時。

根據(jù)需要創(chuàng)建動態(tài)鏈接。當(dāng)程序需要的不是可執(zhí)行文件中的函數(shù) 時,Windows 加載動態(tài)鏈接庫 (DLL) 使其函數(shù)的所有可用于您的應(yīng)用程序。該次 Windows 解析每個函數(shù)的地址,并動態(tài)地將其鏈接到您的應(yīng)用程序。

在 Visual Basic 中使用的所有自定義控件的 dll。唯一的區(qū)別是它們需要特殊處理的 Visual Basic 從收到的郵件。

1.1 為什么使用 dll?

下面是為什么您可能希望使用 DLL 的四個原因:

  • C 運行時函數(shù)的訪問:

    C 運行時庫有許多有用的功能將不可用的 Visual Basic 程序員的 dll 不是。例如對于通過 _dos_getdiskfree 函數(shù)可以計算總的磁盤空間量和可用的驅(qū)動器上可用磁盤空間。
  • 對 Windows API (應(yīng)用程序編程接口) 的訪問功能,需要回調(diào)例程:

    有些 Windows API 函數(shù)要求一個回調(diào)函數(shù)?;卣{(diào)函數(shù)是一個函數(shù),Windows 將調(diào)用該函數(shù)在執(zhí)行 API 時調(diào)用。這種函數(shù)的一個示例是 EnumTaskWindows,將賦予所擁有的特定任務(wù)的所有窗口的句柄。
  • 速 度:

    C 是一個完全編譯的語言,它相當(dāng)接近為本機代碼的級別上工作。這意味著將快速也用 C 編寫的程序的執(zhí)行。
  • 在 使用負載:

    只在需要時才會加載代碼和 DLL 中的數(shù)據(jù)。DLL 可以進行組織,以便只有所需的部件相對于整個 DLL 加載。這樣可以減少所需的內(nèi)存和加載的時間量。

1.2 DLL 的構(gòu)成

每個 DLL 必須包含一個 LibMain 函數(shù),并應(yīng)包含除了導(dǎo)出的函數(shù)可由可執(zhí)行程序調(diào)用的一個 Windows 退出過程 (WEP)。

  • LibMain:

    DLL 必須包含 LibMain 函數(shù)。LibMain 函數(shù)調(diào)用系統(tǒng)以初始化 DLL。LibMain 是只能調(diào)用一次--需要該 DLL 的第一個程序加載時。參數(shù)傳遞給 LibMain 如下:
    對 DLL 的實例的句柄: 句柄。
    -WORD: 庫的數(shù)據(jù)段。
    -WORD: 堆大小。
    -LPSTR: 命令行參數(shù)。
  • WEP:

    卸載磁帶庫之前,WEP (Windows 退出過程) 的 DLL 執(zhí)行清理。雖然 WEP 函數(shù)所必需的以前版本的 Windows 操作系統(tǒng)中的每個 DLL,3.1 版的它是可選的。一個 WEP 應(yīng)包含在模塊定義文件 (.DEF) 中可視的 C,例如:
    導(dǎo)出
    WEP
  • 導(dǎo) 出的函數(shù):

    這些是您要從您的 DLL 中調(diào)用的函數(shù)。它們由 _export 表示。_export 用于向后兼容性。(.DEF) 文件的 DLL 文件中,還必須列出想要調(diào)用的所有功能。

1.3 DLL 內(nèi)存管理問題

使用大的內(nèi)存模型。

C 將存儲為靜態(tài)定義的所有變量或全局 (外部定義的函數(shù)) 將在該程序的堆空間和 C 所有其他變量都存儲在堆棧上。

在中小型模型中所有的指針將默認情況下位于附近。這意味著數(shù)據(jù)訪問數(shù)據(jù)段 (DS) 寄存器中,或堆棧段 (SS) 寄存器的 16 位偏移量。遺憾的是,編譯器有無法知道是否偏移量從 DS 或該 SS。在大多數(shù)程序中這不是問題因為 DS 和 SS 指向同一個網(wǎng)段。一個 DLL 但,是一種特殊情況。

DLL 都有其自己的數(shù)據(jù)段,但與調(diào)用程序共享其堆棧。這意味著 DS 和 $ 在 SS 未指向同一位置。在解決此問題的最簡單方法是生成 DLL 在大內(nèi)存模型中所有變量都引用的值是 32 位的位置。

為什么動態(tài)分配內(nèi)存?

動態(tài)分配的內(nèi)存是 Windows 友好的一項技術(shù)。聲明的數(shù)據(jù)的大型數(shù)組占用的空間限于到 64k 的程序的堆?;蚰绦虻臄?shù)據(jù)段浪費了磁盤空間和 Windows 內(nèi)存中。最好時您需要它,并且在完成后再將其釋放內(nèi)存,詢問 Windows。

分配內(nèi)存

在 Windows 中,您可以動態(tài)地分配兩種類型的本地和全局的內(nèi)存。本地內(nèi)存僅限于 64 的 K,并在一個 DLL 的情況下本地內(nèi)存與調(diào)用 DLL 的程序共享。全局內(nèi)存是內(nèi)存的所有 windows 可用后它已加載。

本地內(nèi)存分配和托管 使用 LocalAlloc、 LocalLock LocalUnlock 和 LocalFree 功能--如下例所示:
   char* pszBuffer;                                                                                            ....                                                                                            pszBuffer = (char *) LocalAlloc (LPTR, 20);                                                                                            ...                                                                                            LocalFree (pszBuffer);                                                                                            
比分配全局內(nèi)存分配本地內(nèi)存將更快。 但是,從本地堆分配僅限于這必須調(diào)用 DLL 的所有程序間共享 64 K。最好使用時小,短壽命的內(nèi)存塊所需的本地內(nèi)存。

全局內(nèi)存分配和托管使用 GlobalAlloc、 GlobalLock GlobalUnlock 和 GlobalFree 功能--如下例所示:
   HGLOBAL hglb;                                                                                            char* pszBuffer;                                                                                            hglb = GlobalAlloc (GHND, 2048);                                                                                            // GHND allocates the memory as moveable and                                                                                            // initialized to 0                                                                                            // 2048 is the amount of memory to be allocated...                                                                                            pszBuffer = GlobalLock (hglb);                                                                                            ...                                                                                            GlobalUnlock (hglb);                                                                                            GlobalFree (hglb);                                                                                            
的 GlobalAlloc 函數(shù)分配內(nèi)存以 4 K 的倍數(shù)增長。

如果您想要共享 DLL 與其他程序中分配的內(nèi)存,您應(yīng)將其使用 GMEM_SHARED 標(biāo)志進行分配。如果您想要共享通過 DDE 內(nèi)存,您必須將其分配使用 GMEM_DDESHARE 標(biāo)志。

是仔細靜態(tài)變量中存儲數(shù)據(jù)時

如果試圖將數(shù)據(jù)存儲在使用全局或靜態(tài)變量的 DLL 中不要會驚訝如果接下來調(diào)用您的 DLL 時,這些值已更改。用這種方式存儲,數(shù)據(jù)將通用的所有訪問此 DLL 的應(yīng)用程序。無論多少應(yīng)用程序使用 DLL,沒有 DLL 的一個實例。若要避免這最好的方法是從 DLL 返回結(jié)構(gòu)并將它們在在需要時再次傳遞。

文件句柄

不能共享應(yīng)用程序或 dll 之間的文件句柄。每個應(yīng)用程序都有其自己的文件句柄的表。兩個應(yīng)用程序可以使用相同的文件使用 DLL,它們必須同時打開的文件分別。

1.4 構(gòu)建使用 Visual c + + DLL

以下是生成使用 Visual c + + DLL 所需步驟:

  1. 啟動 Visual c + +。
  2. 通過從項目菜單中選擇新建創(chuàng)建一個新的項目。選擇以下選項:

    • 將項目類 型設(shè)置為"windows 動態(tài)鏈接庫 (.DLL)"
    • 清除使用 Microsoft 基礎(chǔ)類復(fù)選框。
    您還可以設(shè) 置或以后查看這些選項,通過從選項菜單中選擇項目。
  3. 將現(xiàn)有.C 和.def 文件添加到項目中,通過使用出現(xiàn)時從項目菜單中選擇編輯對話框?;蛘咧苯釉?Visual c + + 編輯窗口中輸入您的代碼。(請參閱下面列出了.C 和.def 示例代碼。
  4. 從項目菜單中選擇生成 <yourname>.DLL 選項。

1.5 示例 C DLL

下面的 DLL 包含 GetDiskInfo 函數(shù)可以從 Visual Basic 中調(diào)用。它將返回可用磁盤空間、 當(dāng)前驅(qū)動器的名稱和卷名。
      C Code Example, DISKINFO.C:                                                                                            #include <windows.h>                                                                                            #include <dos.h>                                                                                            int CALLBACK LibMain (HANDLE hInstance, WORD wDataSeg, WORD wHeapSize,                                                                                            LPSTR lpszCmdLine)                                                                                            // The following is required only under Windows version 3.1                                                                                            // Win32 does not require or support UnlockData()                                                                                            {                                                                                            if (wHeapSize > 0)                                                                                            UnlockData (0);  //Unlocks the data segment of the library.                                                                                            return 1;                                                                                            }                                                                                            void __export CALLBACK GetDiskInfo (char *cDrive, char *szVolumeName,                                                                                            unsigned long *ulFreeSpace)                                                                                            {                                                                                            unsigned drive;                                                                                            struct _diskfree_t driveinfo;                                                                                            struct _find_t c_file;                                                                                            _dos_getdrive (&drive);                                                                                            _dos_getdiskfree( drive, &driveinfo );                                                                                            if (!_dos_findfirst( "*.*", _A_VOLID, &c_file ))                                                                                            wsprintf( szVolumeName, "%s", c_file.name);                                                                                            else                                                                                            wsprintf ( szVolumeName, "NO LABEL");                                                                                            *cDrive = drive + 'A' -1;                                                                                            *ulFreeSpace = (unsigned long) driveinfo.avail_clusters * (unsigned                                                                                            long) driveinfo.sectors_per_cluster * (unsigned long)                                                                                            driveinfo.bytes_per_sector;                                                                                            }                                                                                            
使用 Visual c + + 中的以下 DISKINFO.DEF 文件:
LIBRARY diskinfo
說明 GetDiskInfo 可能從調(diào)用 vba
EXETYPE 窗口 3.1
代碼 PRELOAD 可移動可放棄
數(shù)據(jù) PRELOAD 可移動單
HEAPSIZE 4096
導(dǎo)出
GetDiskInfo @ 1
注: 到.def 文件中的 LIBRARY 名稱必須與 DLL 的文件名稱相同否則 Visual Basic 將為您提供加載 DLL 錯誤。例如對于創(chuàng)建文件 DISKINFO.DLL 上面到.def 文件中使用 LIBRARY DISKINFO 語句。

部分 B

2.0 從 Visual Basic 中調(diào)用的 dll

在 vba 所有的函數(shù)中包括想要調(diào)用的 DLL 函數(shù)必須首先聲明使用 Declare 語句。您可以聲明您在窗體或模塊的聲明部分中的功能。如果您聲明一個 DLL 過程或窗體中的函數(shù),則專用于該窗體。 若要將其公開,您必須在模塊中聲明它。以下是一個示例 Declare 語句:
   Declare Sub getdiskinfo Lib "c:\somepath\diskinfo.dll"                                                                                            (ByVal mydrive As String, ByVal myvolume As String, free As Long)                                                                                            
,必須輸入整個 Declare 語句作為一個,單個行。此特定的聲明語句聲明 GETDISKINFO 位于用戶創(chuàng)建 DISKINFO.DLL 文件在用戶定義的過程。

一旦您聲明該函數(shù),您可以調(diào)用,并使用該函數(shù),就像您將調(diào)用并使用 Visual Basic 函數(shù)。

2.1 DLL 參數(shù)

因為 dll 通常用 C 編寫的 dll 可以使用多種不直接支持 Visual Basic 的參數(shù)。如此一來傳遞參數(shù)時, 必須找到傳遞適當(dāng)?shù)臄?shù)據(jù)類型程序員。

通過值或通過引用傳遞參數(shù)

默認狀態(tài)下,Visual Basic 將通過引用傳遞所有參數(shù)。(當(dāng)通過引用傳遞,Visual Basic 提供 32 位遠地址)。但是,多個 DLL 函數(shù)期望通過值傳遞的參數(shù)。這可通過將放在參數(shù)聲明的前面 ByVal 關(guān)鍵字來實現(xiàn)。

以 下各節(jié)介紹如何將參數(shù)轉(zhuǎn)換為 Visual Basic。

8 到 16 位數(shù)字參數(shù)

將 8 到 16 位數(shù)字參數(shù) (int、 較短的無符號整數(shù)、 無符號的短、 BOOL 和 WORD) 作為整型傳遞。

32 位數(shù)字參數(shù)

將 32 位數(shù)值參數(shù)傳遞 (長,無符號長整型,和 DWORD) 為 LONG。

對象句柄

所有句柄是與窗口相關(guān)聯(lián)的 16 位的唯一整數(shù)值和通過值傳遞,因此將作為整型傳遞,這些參數(shù)。

字符串

字符串包含 LPSTR 和 LPBYTE 的數(shù)據(jù)類型 (指向字符的指針) 或為無符號的字符的指針。將作為 (ByVal paramname 為 String) 傳遞這些參數(shù)。若要直接傳遞 Visual Basic 字符串,請將它們作為 (字符串為參數(shù)) 傳遞。

在 Visual Basic 和 C DLL 之間傳遞字符串上的其他信息,請參閱 Microsoft 知識庫中下面的文章:
118643  (http://support.microsoft.com/kb/118643/EN-US/ ) 如何傳遞一個字符串?dāng)?shù)組 VB 和 C 的 DLL 之間
注意: Visual Basic 字符串需要不通過字符串直接,除非該 DLL 顯式要求這樣的特殊處理。

數(shù)值的指針

將指針傳遞給數(shù)字值,只需不使用 ByVal 關(guān)鍵字。

結(jié)構(gòu)

如果在 Visual Basic 用戶定義的類型與所需的 DLL 結(jié)構(gòu)相匹配,可以通過引用傳遞結(jié)構(gòu)。

注 意: 不能通過值傳遞結(jié)構(gòu)。

數(shù)組的指針

通過引用傳遞數(shù)組的第一個元素。

指向函數(shù)的指針

Visual Basic 不支持回調(diào)函數(shù),因此 Visual basic,不能使用具有指向函數(shù)的 DLL 函數(shù)。

空指針

如果 DLL 需要 Null 指針,將作為 (ByVal paramname As Any) 傳遞它。您可以使用 0 和 paramname 時調(diào)用該 DLL 中的值。

2.2 疑難解答

以下是您可能會遇到一些問題的解決方案。

之后調(diào)用該 DLL 系統(tǒng)資源保留: 低

如果您的 DLL 使用的 GDI 對象,您必須記住它們在使用后釋放它們。這可能不是很明顯,Visual Basic 中,但如果您創(chuàng)建一個 GDI 對象 (例如對于 CreateBrushIndirect),請使用 Windows SDK (軟件開發(fā)工具包) 時, 您必須將其刪除在以后使用 DeleteObject。

錯誤的 DLL 調(diào)用約定錯誤

此錯誤通常被引起錯誤地省略或包括 ByVal 關(guān)鍵字從聲明語句。如果傳遞錯誤的參數(shù),也可能導(dǎo)致此錯誤。

在加載 DLL 的錯誤

調(diào)用動態(tài)鏈接庫的過程和過程的聲明語句中指定該文件不能被加載時,會發(fā)生此錯誤。您可以使用 Microsoft Windows API 函數(shù) LoadLibrary 以了解有關(guān) DLL 加載失敗的更具體的信息。

一 般保護 (GP) 錯誤

您的程序?qū)懭氩粚儆谒膬?nèi)存塊時,就會發(fā)生 GP 錯誤。對于這兩個的最可能原因是:

  • overstepped 了數(shù)組界限。C 不檢查正在寫入該數(shù)組下標(biāo)無效。因此,您可以輕松地寫入不屬于您的內(nèi)存。
  • 您已經(jīng)將一個內(nèi)存位置使用的指針。最佳 的選擇是將 NULL 給所有的指針后釋放其內(nèi)存。
不正確的變量類型傳遞給 DLL 函數(shù)時,也會發(fā)生 GP 故障。

2.3 示例 Visual Basic 電話程序

沒有要在 vba 程序中調(diào)用 DLL 的兩個部分。首先,您將聲明功能,然后您它在代碼中使用事件。

下 面是一個聲明語句的示例。在模塊中或在窗體的通用聲明部分中,應(yīng)將放在聲明語句。
   ' Enter the following Declare as one, single line:                                                                                            Declare Sub getdiskinfo Lib "c:\dllartic\diskinfo.dll"                                                                                            (ByVal mydrive As String, ByVal myvolume As String, free As Long)                                                                                            
指定 ByVal 語句完全如下所示,否則 GP 故障可能會發(fā)生。

一旦聲明的函數(shù) 就可以在事件代碼中使用。下面的示例使用從 DLL 函數(shù)在 Command1 Click 的事件代碼:
   Sub Command1_Click ()                                                                                            Dim drive As String * 1                                                                                            Dim volume As String * 20                                                                                            Dim free As Long                                                                                            Call getdiskinfo(drive, volume, free)                                                                                            Text1.Text = drive                                                                                            Text2.Text = volume                                                                                            Text3.Text = Str$(free)                                                                                            End Sub                                                                                            

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
開始進行 64位 Windows 系統(tǒng)編程之前需要了解的所有信息
Visual Basic 和 C 之間傳遞數(shù)組的方法
MATLAB與Visual?Basic
托管DLL和非托管DLL的區(qū)別
Asc/AscB/AscW和Chr/ChrB/ChrW函數(shù)之間的區(qū)別 | Demon''s Blog
WINDOWS API 程序設(shè)計(第一章:開始) | 博客網(wǎng)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服