在易語言中調用DLL(共9頁)_第1頁
在易語言中調用DLL(共9頁)_第2頁
在易語言中調用DLL(共9頁)_第3頁
在易語言中調用DLL(共9頁)_第4頁
在易語言中調用DLL(共9頁)_第5頁
已閱讀5頁,還剩7頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、易語言中調用(dioyng)DLL使用說明基本(jbn)說明本文(bnwn)所描述的部分功能需易語言4.01或以上版本支持。“在易語言中調用DLL”包含兩方面的內容:調用Windows系統API函數;調用普通DLL函數。下文用到的“調用API”或“調用DLL”等字眼,除非特別注明,一般都是指以上兩方面之一或之和,視上下文而定。絕大多數情況下,無需明確區分調用的是系統API還是普通DLL。目前易語言只支持以stdcall方式調用DLL中的導出函數。Windows系統API一般都是以stdcall調用方式導出的,故在易語言中調用它們時通常不必考慮函數調用方式的問題。而普通DLL有可能導出“非std

2、call調用方式”(比如cdecl)的函數,調用時需要特別注意。一般而言,考慮到通用性,DLL開發者都會選擇導出以sdtcall方式調用的函數。(支持生成DLL的編程語言通常都支持導出stdcall調用方式的函數,具體實現請參考各編程語言手冊。)特別地,在VC中類似如下代碼導出的函數并非stdcall調用方式:extern C_declspec (dllexport) test(int a, int b)return (a + b);要想該函數被易語言調用,應該按類似如下方式定義(并在.def文本中聲明導出):int WINAPI test (int a, int b)return (a +

3、b);易語言編譯生成的DLL,其導出函數全部為stdcall調用方式,所以在易語言中調用易語言生成的DLL不存在問題。目前在易語言中調用DLL時只支持1字節對齊的結構(自定義數據類型)如果DLL命令的某個參數或參數的某個成員是結構類型(自定義數據類型),則其對齊方式必須是1字節對齊。Windows系統API中所用到的結構都是1字節對齊的,故在調用API時不受此限制。但如果想用其它編程語言生成DLL供易語言調用且數據類型中包含了1或2字節數據長度的成員(如字符型或短整數),就需要考慮結構的1字節對齊。在VC中,可以這樣定義1字節對齊的結構(結構在C/C+中稱為struct):#pragma pa

4、ck (push, old_value) / 保存VC+編譯器結構對齊字節數。#pragma pack (1) / 設置為以一字節對齊。struct xxxbyte a;int b;double c;#pragma pack (pop, old_value) / 恢復VC+編譯器結構對齊字節數。在Delphi中,可以(ky)這樣定義1字節對齊的結構(結構(jigu)在Delphi中稱為(chn wi)record):type xxx = packed record a: byte; b: integer; c: double;end;在其它編程語言或編譯器中的定義方式請參考各自的編程手冊。目前

5、易語言支持調用任意復雜的DLL命令只要滿足了前面的兩個條件調用方式為stdcall,參數結構為1字節對齊易語言支持調用任意復雜的DLL命令:參數除了可以是基本數據類型或普通結構類型外,還可以是基本類型地址或基本類型數組,也可以是結構類型地址或結構類型數組,結構類型的成員中還可以包含任意數量和任意層次的其它結構、結構地址、結構數組,等等。DLL命令調用表要在易語言中調用Windows API或普通DLL中的導出函數,必須首先在易語言中對該函數進行聲明,聲明的方式就是頗具易語言特色的“填寫DLL命令調用表”。“DLL命令調用表”正確填寫完畢之后,就可以象調用普通易語言子程序一樣調用DLL命令了。在

6、易語言中填寫“DLL命令調用表”與在VB中聲明DLL函數是同樣的作用,具有等同的效果。只不過易語言把原本文本型的東西表格化了,更加直觀,便于編輯修改。易語言中的表格與其它編程工具中的普通文本一樣,可以被復制和粘貼。下面重點說明“DLL命令調用表”的填寫。在易語言中,選擇菜單“插入DLL命令”即可插入一個空白的“DLL命令調用表”。當然還有其它操作方式,請參考易語言相關操作手冊。空白的“DLL命令調用表”已填寫的“DLL命令調用表”要填寫的項目說明Dll命令名定義該DLL命令在易語言中的名稱。必須填寫,但具體什么名稱并不重要,只要不與易語言中的其它子程序重名即可。返回值類型定義DLL命令的實際返

7、回值類型所對應的易語言類型。如果在易語言中調用該DLL函數時不需要用到其返回值,可以不填寫而不管實際的DLL函數有沒有返回值。易語言中的數據類型與生成該DLL的編程語言中的數據類型并不完全一致,需進行適當的轉換,詳見下文數據類型對照表。公開目前不被使用。(Dll命令)備注對該DLL的注釋,可以不填。Dll庫文件名指定被調用的DLL文件名稱。文件名中的英文字母不區分大小寫,可以省略后綴“.dll”。如果是Windows系統DLL的話,可以省略不填。可以使用絕對路徑或相對路徑,使用相對路徑時路徑相對于當前“.e”文件(調試運行時)或當前“.exe”文件(編譯后運行時)。考慮到通用性,不建議在此處指

8、定路徑,可在代碼中以“置DLL裝載目錄()”動態指定被調用DLL的路徑。在Dll庫中對應命令名指定被調用的DLL命令(或函數)名稱。必須準確填寫。名稱中的英文字母不區分大小寫。注意:某些帶文本參數的API,其函數名稱通常以“A”或“W”結尾。如FindWindow函數,其實user32.dll中只有FindWindowA和FindWindowW,并沒有FindWindow,所以我們在這里要填FindWindowA和FindWindowW而不是FindWindow。參數名定義該DLL命令在易語言中的名稱。必須填寫,但具體什么名稱并不重要。(Dll參數)類型定義該參數的實際類型所對應的易語言類型。

9、可以為易語言自定義數據類型(該數據類型的成員必須與DLL所需數據類型的成員一一對應)。易語言中的數據類型與生成該DLL的編程語言中的數據類型并不完全一致,需進行適當的轉換,詳見下文數據類型對照表。傳址如果選中本標志,表示將傳遞參數的內存首地址(類似C/C+中的傳指針參數或VB中的ByRef參數或Delphi中的var參數);如果不選中本標志,表示傳遞參數實際數據。應根據該DLL的參數聲明或參數說明來決定是否使用“傳址”,詳見示例。此外,如果參數為文本型、字節集型,或者為數組數據,則總是傳址(而不管此處是否定義為傳址)。數組指定是否傳入數組數據。應根據該DLL的參數聲明或參數說明來決定是否使用“

10、數組”,詳見示例。(Dll參數)備注對該參數的注釋,可以不填。注:上表(shn bio)中所謂“實際(shj)(數據(shj))類型”表示在生成該DLL的編程語言中參數或返回值的數據類型。易語言與VB,C/C+, API的數據類型對照表(待更新):易語言VBC/C+, API整數型Longint, long, bool, INT, LONG, BOOL, DWORD, UINT, LRESULT,WPARAM, LPARAM, HWND, HFILE, HMODULE, 文本型Stringchar*, LPSTR, LPTSTR, LPCSTR, LPCTSTR邏輯型Longint, INT,

11、 BOOL字節集型Void*, LPVOID小數型SingleFloat雙精度小數型Double, CurrencyDouble日期時間型DateDATE字節型Bytebyte, char, bool, BYTE, CHAR短整數型Integer, Booleanshort, SHORT, WORD長整數型_int64, INT64注1:固定長度(chngd)的文本(如VB中的“Dim s As String * 32”或C/C+中的“char s32;”)在易語言中應定義為相應(xingyng)長度的字節型數組,并傳址。注2:各編程語言之間數據類型相互對照的一般(ybn)原則是“所占內存字節

12、數相同”。注3:VB的Integer,Bool均占兩個字節內存,而易語言的“整數型”“邏輯型”均占四個字節內存,注意區分。注4:如果不能確信其它編程語言中的某個數據類型對應易語言的哪個類型,可首先嘗試“整數型”,然后可嘗試“字節集”(注意使用前以“取空白字節集()”等命令分配足夠的內存空間)。注5:有些API(如FindWindow(A))的文本參數需要接收NULL值,有兩種處理方案:在易語言中將該參數定義為整數型并傳入0;在易語言中將該參數定義為文本型并傳入“字符(0)”(在這里“字符(0)”類似于VB中的vbNullString)。自定義數據類型如果DLL命令中有參數為結構類型,就需要事先

13、在易語言中定義與其對應的自定義數據類型。定義自定義數據類型的成員,與定義DLL命令的參數基本相同(具體含義請參考上文),只是有一點不同:如果DLL命令參數為數組,將忽略“傳址”設置并總是認為“傳址”;但如果自定義數據類型成員為數組,“傳址”與否有不同的含義。此外,自定義數據類型的成員“數組”屬性需指定一個明確的數值,而不象DLL命令參數那樣僅僅設置一個標志。在自定義數據類型的成員為數組時,如果設置“傳址”,表示在此自定義數據類型中該成員位置處只存儲數組數據的內存首地址;如果不設置傳址,表示在此自定義數據類型中該成員位置處的數據為所有數組數據的順序排放。至于如何判斷某自定義數據類型成員是否為“數

14、組”及是否應該“傳址”,則應視具體的自定義數據類型及其說明文檔而定,有時還需考慮該成員的“語義”。下面舉例說明,請看CPINFO這個結構的C/C+定義及其對應的易語言自定義數據類型:C/C+定義易語言定義struct _cpinfo UINT HYPERLINK MaxCharSize; BYTE HYPERLINK DefaultCharMAX_DEFAULTCHAR; BYTE HYPERLINK LeadByteMAX_LEADBYTES; CPINFO, *LPCPINFO;CPINFO的最后兩個成員都是字節型數組,且不是地址,所以應將其分別定義為“字節型”“數組”(數組長度分別為MA

15、X_DEFAULTCHAR 和MAX_LEADBYTES,查VC相應頭文件得知兩個常量的值分別是2和12)。自定義數據類型成員是數組且需要“傳址”的情況比較少見,暫舉一例:C/C+定義易語言定義struct x_Info DWORD* value; CHAR* pChars; /指向一個256字符長度的緩沖區 XINFO, *LPXPINFO;其它(qt)的自定義數據類型實例(shl):錯誤(cuw)及處理如果易語言運行時提示“無法找到指定DLL庫文件*中的輸出命令*”,往往會有以下幾種情況:DLL調用表中,填寫“Dll庫文件名”或“在Dll庫中對應命令名”時出現打字錯誤;指定的“Dll庫文件

16、名”不在當前目前,也不在Windows系統目錄,也不在特定目錄中;指定的“Dll庫文件名”中只有*A或*W函數,而沒有*函數;Dll編寫時失誤,沒有導出相應的函數,或導出了類似“?testYAHHHZ”的奇怪函數(通常是因為忘記在C+中將該函數聲明為extern “C”);如果易語言在運行時提示“調用DLL命令后發現堆棧錯誤”,通常是因為:DLL調用表中,對該DLL命令的參數定義錯誤,或數據類型不準確,或多提供了參數,或少提供了參數;或錯誤使用了傳址,或錯誤使用了數組;如果某參數的類型為自定義類型,其成員定義錯誤,或數據類型不準確,或多提供了成員,或少提供了成員;或錯誤使用了傳址,或錯誤使用了

17、數組;該DLL命令的調用方式并非stdcall易語言目前不支持調用非stdcall調用方式的DLL命令,見上文;示例(shl)下面(xi mian)以幾個具體的DLL的調用(dioyng)來說明其使用方法(重點是“DLL命令調用表”的填寫)首先要說明是,要在易語言在調用系統API或普通DLL,必須要有欲調用函數詳細說明。對于系統API函數,微軟的MSDN有詳細的說明文檔;網絡上也有不少網友整理的針對VB的API函數說明。對于普通DLL,其作者通常會附帶相應的說明。以下例子以網上流行較廣的“VBAPI函數參考手冊BSL軟件工作室”(CHM,中文)作為主要參考資料,以MSDN(英文)作為輔助資料因

18、為前者有的地方說明不夠詳細和深入,搜集的API也不十分全面。首先看一個在易語言中調用API函數PolyBezier畫賽貝爾曲線的例子。因為PolyBezier需要一個“設備場景句柄”參數,所以還要引入另外兩個API函數GetDC和ReleaseDC以分別獲取和釋放“設備場景句柄”。我們先來看GetDC的VB聲明:GetDCDeclare Function GetDC Lib user32 Alias GetDC (ByVal hwnd As Long) As Long說明:獲取指定窗口的設備場景返回值:Long,指定窗口的設備場景句柄,出錯則為0。參數名稱參數類型及說明hWndLong,將獲取

19、其設備場景的窗口的句柄。若為0,則要獲取整個屏幕的DC根據上表的VB聲明,可以得知,GetDC位于動態庫“user32”中,其實際函數名稱為“GetDC”;其返回值類型是Long,對應易語言中的“整數型”;其參數hWnd的類型是Long,也對應易語言中的“整數型”,同時因為關鍵字ByVal的存在,表示該參數并非“傳址”參數。根據以上分析,可以得到以下易語言DLL調用表:再看ReleaseDC的VB聲明:ReleaseDCDeclare Function ReleaseDC Lib user32 Alias ReleaseDC (ByVal hwnd As Long, ByVal hdc As

20、Long) As Long說明:釋放由調用 HYPERLINK mk:MSITStore:E:liigo共享編程Win%20APIvbapi.chm:/GetDC.htm GetDC或 HYPERLINK mk:MSITStore:E:liigo共享編程Win%20APIvbapi.chm:/GetWindowDC.htm GetWindowDC函數獲取的指定設備場景。返回值:Long,執行成功為1,否則為0。參數名稱參數類型及說明hWndLong,要釋放的設備場景相關的窗口句柄hDCLong,要釋放的設備場景句柄根據上表的VB聲明,可以得知,ReleaseDC位于(wiy)動態庫“user3

21、2”中,其實際(shj)函數名稱為“ReleaseDC”;其返回值類型(lixng)為Long,按說應該對應易語言中的“整數型”,但根據其語義(說明中明確指出返回值表示該函數是否執行成功,應是邏輯型值),我們選擇將其定義為“邏輯型”當然定義為“整數型”也是對的。它的兩個參數類型都是Long,對應易語言中的“整數型”,且都有ByVal關鍵字,表示并非傳址。根據以上分析,可以得到以下易語言DLL調用表:最后看PolyBezier的VB聲明:PolyBezierDeclare Function PolyBezier& Lib gdi32 (ByVal hdc As Long, lppt As POI

22、NTAPI, ByVal cPoints As Long)說明:描繪一條或多條貝塞爾(Bezier)曲線。返回值:Long,非零表示成功,零表示失敗。參數名稱參數類型及說明hdcLong,要在其中繪圖的設備場景lppt HYPERLINK mk:MSITStore:E:liigo共享編程Win%20APIvbapi.chm:/POINTAPI.htm POINTAPI,指定一個 HYPERLINK mk:MSITStore:E:liigo共享編程Win%20APIvbapi.chm:/POINTAPI.htm POINTAPI結構數組。其中的第一個結構指定了起點。剩下的點三個一組包括兩個控件點

23、和一個終點原文:An array of HYPERLINK mk:MSITStore:E:liigo共享編程Win%20APIvbapi.chm:/POINTAPI.htm POINTAPI structures. The first structure specifies the starting point. The remaining points are in groups of three, consisting of two control points and an end point.cPointsLong,lppt數組的總點數根據上表,可以得知,PolyBezier函數位于動

24、態庫“gdi32”中;返回值類型為Long,根據語義我們選擇定義為易語言中的“邏輯型”(理由同上);第一個和第三個參數都是Long,均對應易語言中的“整數型”;第二個參數,根據參數說明可知它是一個“指向POINTAPI結構數組的指針”,參數類型為“POINTAPI”(后面將為這個結構定義一個易語言自定義數據類型),“數組”,“傳址”。根據以上分種,得到了易語言DLL調用表:因為上面用到了結構POINTAPI,我們需要將它定義(dngy)為易語言自定義數據類型。它有兩個成員,參數都是Long,對應易語言中的“整數型”:到此為止,已將所需的DLL命令及其自定義數據類型定義好了,下面就可以象調用易語言普通子程序一樣(yyng)調用這幾個DLL命令了:其它(qt)的DLL命令調用表實例:注意上面兩圖的“在Dll庫中對應命令名”一欄,命令最后都有一個字符“A”,在其VB聲明中就可找出其來源:Declare Function OpenPrinter Lib winspool.drv Alias OpenPrinterA (ByVal

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論