日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Delphi环境中编写调用DLL的方法和技巧

發(fā)布時(shí)間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Delphi环境中编写调用DLL的方法和技巧 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Delphi環(huán)境中編寫(xiě)調(diào)用DLL的方法和技巧

第一章 為什么要使用動(dòng)態(tài)鏈接庫(kù)(DLL) top
提起DLL您一定不會(huì)陌生,在Windows中有著大量的以DLL為后綴的文件,它們是保證Windows正常運(yùn)行和維護(hù)升級(jí)的重要保證。(舉個(gè)例子,筆者的Win95 System目錄下盡有500多個(gè)DLL文件。)其實(shí),DLL是一種特殊的可執(zhí)行文件。說(shuō)它特殊主要是因?yàn)橐话闼疾荒苤苯舆\(yùn)行,需要宿主程序比如*.EXE程序或其他DLL的動(dòng)態(tài)調(diào)用才能夠使用。簡(jiǎn)單的說(shuō),在通常情況下DLL是經(jīng)過(guò)編譯的函數(shù)和過(guò)程的集合。
使用DLL技術(shù)主要有以下幾個(gè)原因:

一、減小可執(zhí)行文件大小。
DLL技術(shù)的產(chǎn)生有很大一部分原因是為了減小可執(zhí)行文件的大小。當(dāng)操作系統(tǒng)進(jìn)入Windows時(shí)代后,其大小已經(jīng)達(dá)到幾十兆乃至幾百兆。試想如果還是使用DOS時(shí)代的單執(zhí)行文件體系的話(huà)一個(gè)可執(zhí)行文件的大小可能將達(dá)到數(shù)十兆,這是大家都不能接受的。解決的方法就是采用動(dòng)態(tài)鏈接技術(shù)將一個(gè)大的可執(zhí)行文件分割成許多小的可執(zhí)行程序。

二、實(shí)現(xiàn)資源共享。
這里指的資源共享包括很多方面,最多的是內(nèi)存共享、代碼共享等等。早期的程序員經(jīng)常碰到這樣的事情,在不同的編程任務(wù)中編寫(xiě)同樣的代碼。這種方法顯然浪費(fèi)了很多時(shí)間,為了解決這個(gè)問(wèn)題人們編寫(xiě)了各種各樣的庫(kù)。但由于編程語(yǔ)言和環(huán)境的不同這些庫(kù)一般都不能通用,而且用戶(hù)在運(yùn)行程序時(shí)還需要這些庫(kù)才行,極不方便。DLL的出現(xiàn)就像制定了一個(gè)標(biāo)準(zhǔn)一樣,使這些庫(kù)有了統(tǒng)一的規(guī)范。這樣一來(lái),用不同編程語(yǔ)言的程序員可以方便的使用用別的編程語(yǔ)言編寫(xiě)的DLL。另外,DLL還有一個(gè)突出的特點(diǎn)就是在內(nèi)存中只裝載一次,這一點(diǎn)可以節(jié)省有限的內(nèi)存,而且可以同時(shí)為多個(gè)進(jìn)程服務(wù)。

三、便于維護(hù)和升級(jí)。
細(xì)心的朋友可能發(fā)現(xiàn)有一些DLL文件是有版本說(shuō)明的。(查看DLL文件的屬性可以看到,但不是每一個(gè)DLL文件都有)這是為了便于維護(hù)和升級(jí)。舉個(gè)例子吧,早期的Win95中有一個(gè)BUG那就是在閏年不能正確顯示2月29日這一天。后來(lái),Microsoft發(fā)布了一個(gè)補(bǔ)丁程序糾正了這個(gè)BUG。值得一提的是,我們并沒(méi)有重裝Win95,而是用新版本的DLL代替了舊版本的DLL。(具體是哪一個(gè)DLL文件筆者一時(shí)想不起來(lái)了。)另一個(gè)常見(jiàn)的例子是驅(qū)動(dòng)程序的升級(jí)。例如,著名的DirectX就多次升級(jí),現(xiàn)在已經(jīng)發(fā)展到了6.0版了。更妙的是,當(dāng)我們?cè)噲D安裝較低版本的DLL時(shí),系統(tǒng)會(huì)給我們提示,避免人為的操作錯(cuò)誤。例如我們升級(jí)某硬件的驅(qū)動(dòng)程序時(shí),經(jīng)常碰到Windows提示我們當(dāng)前安裝的驅(qū)動(dòng)程序比原來(lái)的驅(qū)動(dòng)程序舊。

四、比較安全。
這里說(shuō)的安全也包括很多方面。比如,DLL文件遭受病毒的侵害機(jī)率要比普通的EXE文件低很多。另外,由于是動(dòng)態(tài)鏈接的,這給一些從事破壞工作的“高手”們多少帶來(lái)了一些反匯編的困難。

第二章 在Delphi中編寫(xiě)DLL top

注意:在這里筆者假定讀者使用的是Delphi 3或Delphi 4開(kāi)場(chǎng)白說(shuō)了那么多,總該言歸正傳了。編寫(xiě)DLL其實(shí)也不是一件十分困難的事,只是要注意一些事項(xiàng)就夠了。為便于說(shuō)明,我們先舉一個(gè)例子。

library Delphi;

uses
SysUtils,
Classes;

function TestDll(i:integer):integer;stdcall;
begin
Result:=i;
end;

exports
TestDll;

begin
end.

上面的例子是不是很簡(jiǎn)單?熟悉Delphi的朋友可以看出以上代碼和一般的Delphi程序的編寫(xiě)基本是相同的,只是在TestDll函數(shù)后多了一個(gè)stdcall參數(shù)并且用exports語(yǔ)句聲明了TestDll函數(shù)。只要編譯上面的代碼,就可以得到一個(gè)名為Delphi.dll的動(dòng)態(tài)鏈接庫(kù)。現(xiàn)在,讓我們來(lái)看看有哪些需要注意的地方。 一、在DLL中編寫(xiě)的函數(shù)或過(guò)程都必須加上stdcall調(diào)用參數(shù)。在Delphi 1或Delphi 2環(huán)境下該調(diào)用參數(shù)是far。從Delphi 3以后將這個(gè)參數(shù)變?yōu)榱藄tdcall,目的是為了使用標(biāo)準(zhǔn)的Win32參數(shù)傳遞技術(shù)來(lái)代替優(yōu)化的register參數(shù)。忘記使用stdcall參數(shù)是常見(jiàn)的錯(cuò)誤,這個(gè)錯(cuò)誤不會(huì)影響DLL的編譯和生成,但當(dāng)調(diào)用這個(gè)DLL時(shí)會(huì)發(fā)生很?chē)?yán)重的錯(cuò)誤,導(dǎo)致操作系統(tǒng)的死鎖。原因是register參數(shù)是Delphi的默認(rèn)參數(shù)。

二、所寫(xiě)的函數(shù)和過(guò)程應(yīng)該用exports語(yǔ)句聲明為外部函數(shù)。
正如大家看到的,TestDll函數(shù)被聲明為一個(gè)外部函數(shù)。這樣做可以使該函數(shù)在外部就能看到,具體方法是單激鼠標(biāo)右鍵用“快速查看(Quick View)”功能查看該DLL文件。(如果沒(méi)有“快速查看”選項(xiàng)可以從Windows CD上安裝。)TestDll函數(shù)會(huì)出現(xiàn)在Export Table欄中。另一個(gè)很充分的理由是,如果不這樣聲明,我們編寫(xiě)的函數(shù)將不能被調(diào)用,這是大家都不愿看到的。

三、當(dāng)使用了長(zhǎng)字符串類(lèi)型的參數(shù)、變量時(shí)要引用ShareMem。
Delphi中的string類(lèi)型很強(qiáng)大,我們知道普通的字符串長(zhǎng)度最大為256個(gè)字符,但Delphi中string類(lèi)型在默認(rèn)情況下長(zhǎng)度可以達(dá)到2G。(對(duì),您沒(méi)有看錯(cuò),確實(shí)是兩兆。)這時(shí),如果您堅(jiān)持要使用string類(lèi)型的參數(shù)、變量甚至是記錄信息時(shí),就要引用ShareMem單元,而且必須是第一個(gè)引用的。既在uses語(yǔ)句后是第一個(gè)引用的單元。如下例:
uses
ShareMem,
SysUtils,
Classes;
還有一點(diǎn),在您的工程文件(*.dpr)中而不是單元文件(*.pas)中也要做同樣的工作,這一點(diǎn)Delphi自帶的幫助文件沒(méi)有說(shuō)清楚,造成了很多誤會(huì)。不這樣做的話(huà),您很有可能付出死機(jī)的代價(jià)。避免使用string類(lèi)型的方法是將string類(lèi)型的參數(shù)、變量等聲明為Pchar或ShortString(如:s:string[10])類(lèi)型。同樣的問(wèn)題會(huì)出現(xiàn)在當(dāng)您使用了動(dòng)態(tài)數(shù)組時(shí),解決的方法同上所述。

第三章 在Delphi中靜態(tài)調(diào)用DLL top

調(diào)用一個(gè)DLL比寫(xiě)一個(gè)DLL要容易一些。首先給大家介紹的是靜態(tài)調(diào)用方法,稍后將介紹動(dòng)態(tài)調(diào)用方法,并就兩種方法做一個(gè)比較。同樣的,我們先舉一個(gè)靜態(tài)調(diào)用的例子。

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

//本行以下代碼為我們真正動(dòng)手寫(xiě)的代碼

function TestDll(i:integer):integer;stdcall;
external ’Delphi.dll’;

procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=IntToStr(TestDll(1));
end;

end.

上面的例子中我們?cè)诖绑w上放置了一個(gè)編輯框(Edit)和一個(gè)按鈕(Button),并且書(shū)寫(xiě)了很少的代碼來(lái)測(cè)試我們剛剛編寫(xiě)的Delphi.dll。大家可以看到我們唯一做的工作是將TestDll函數(shù)的說(shuō)明部分放在了implementation中,并且用external語(yǔ)句指定了Delphi.dll的位置。(本例中調(diào)用程序和Delphi.dll在同一個(gè)目錄中。)讓人興奮的是,我們自己編寫(xiě)的TestDll函數(shù)很快被Delphi認(rèn)出來(lái)了。您可做這樣一個(gè)實(shí)驗(yàn):輸入“TestDll(”,很快Delphi就會(huì)用fly-by提示條提示您應(yīng)該輸入的參數(shù)是什么,就像我們使用Delphi中定義的其他函數(shù)一樣簡(jiǎn)單。注意事項(xiàng)有以
下一些:

一、調(diào)用參數(shù)用stdcall。
和前面提到的一樣,當(dāng)引用DLL中的函數(shù)和過(guò)程時(shí)也要使用stdcall參數(shù),原因和前面提到的一樣。

二、用external語(yǔ)句指定被調(diào)用的DLL文件的路徑和名稱(chēng)。
正如大家看到的,我們?cè)趀xternal語(yǔ)句中指定了所要調(diào)用的DLL文件的名稱(chēng)。沒(méi)有寫(xiě)路徑是因?yàn)樵揇LL文件和調(diào)用它的主程序在同一目錄下。如果該DLL文件在C:\,則我們可將上面的引用語(yǔ)句寫(xiě)為external ’C:\Delphi.dll’。注意文件的后綴.dll必須寫(xiě)上。

三、不能從DLL中調(diào)用全局變量。
如果我們?cè)贒LL中聲明了某種全局變量,如:var s:byte 。這樣在DLL中s這個(gè)全局變量是可以正常使用的,但s不能被調(diào)用程序使用,既s不能作為全局變量傳遞給調(diào)用程序。不過(guò)在調(diào)用程序中聲明的變量可以作為參數(shù)傳遞給DLL。

四、被調(diào)用的DLL必須存在。
這一點(diǎn)很重要,使用靜態(tài)調(diào)用方法時(shí)要求所調(diào)用的DLL文件以及要調(diào)用的函數(shù)或過(guò)程等等必須存在。如果不存在或指定的路徑和文件名不正確的話(huà),運(yùn)行主程序時(shí)系統(tǒng)會(huì)提示“啟動(dòng)程序時(shí)出錯(cuò)”或“找不到*.dll文件”等運(yùn)行錯(cuò)誤。

第四章 在Delphi中動(dòng)態(tài)調(diào)用DLL top

動(dòng)態(tài)調(diào)用DLL相對(duì)復(fù)雜很多,但非常靈活。為了全面的說(shuō)明該問(wèn)題,這次我們舉一個(gè)調(diào)用由C++編寫(xiě)的DLL的例子。首先在C++中編譯下面的DLL源程序。

#include

extern ”C” _declspec(dllexport)
int WINAPI TestC(int i)
{
return i;
}

編譯后生成一個(gè)DLL文件,在這里我們稱(chēng)該文件為Cpp.dll,該DLL中只有一個(gè)返回整數(shù)類(lèi)型的函數(shù)TestC。為了方便說(shuō)明,我們?nèi)匀灰蒙厦娴恼{(diào)用程序,只是將原來(lái)的Button1Click過(guò)程中的語(yǔ)句用下面的代碼替換掉了。

procedure TForm1.Button1Click(Sender: TObject);
type
TIntFunc=function(i:integer):integer;stdcall;
var
Th:Thandle;
Tf:TIntFunc;
Tp:TFarProc;
begin
Th:=LoadLibrary(’Cpp.dll’); {裝載DLL}
if Th>0 then
try
Tp:=GetProcAddress(Th,PChar(’TestC’));
if Tp<>nil
then begin
Tf:=TIntFunc(Tp);
Edit1.Text:=IntToStr(Tf(1)); {調(diào)用TestC函數(shù)}
end
else
ShowMessage(’TestC函數(shù)沒(méi)有找到’);
finally
FreeLibrary(Th); {釋放DLL}
end
else
ShowMessage(’Cpp.dll沒(méi)有找到’);
end;

大家已經(jīng)看到了,這種動(dòng)態(tài)調(diào)用技術(shù)很復(fù)雜,但只要修改參數(shù),如修改LoadLibrary(’Cpp.dll’)中的DLL名稱(chēng)為’Delphi.dll’就可動(dòng)態(tài)更改所調(diào)用的DLL。

一、定義所要調(diào)用的函數(shù)或過(guò)程的類(lèi)型。
在上面的代碼中我們定義了一個(gè)TIntFunc類(lèi)型,這是對(duì)應(yīng)我們將要調(diào)用的函數(shù)TestC的。在其他調(diào)用情況下也要做同樣的定義工作。并且也要加上stdcall調(diào)用參數(shù)。

二、釋放所調(diào)用的DLL。
我們用LoadLibrary動(dòng)態(tài)的調(diào)用了一個(gè)DLL,但要記住必須在使用完后手動(dòng)地用FreeLibrary將該DLL釋放掉,否則該DLL將一直占用內(nèi)存直到您退出Windows或關(guān)機(jī)為止。

現(xiàn)在我們來(lái)評(píng)價(jià)一下兩種調(diào)用DLL的方法的優(yōu)缺點(diǎn)。靜態(tài)方法實(shí)現(xiàn)簡(jiǎn)單,易于掌握并且一般來(lái)說(shuō)稍微快一點(diǎn),也更加安全可靠一些;但是靜態(tài)方法不能靈活地在運(yùn)行時(shí)裝卸所需的DLL,而是在主程序開(kāi)始運(yùn)行時(shí)就裝載指定的DLL直到程序結(jié)束時(shí)才釋放該DLL,另外只有基于編譯器和鏈接器的系統(tǒng)(如Delphi)才可以使用該方法。動(dòng)態(tài)方法較好地解決了靜態(tài)方法中存在的不足,可以方便地訪(fǎng)問(wèn)DLL中的函數(shù)和過(guò)程,甚至一些老版本DLL中新添加的函數(shù)或過(guò)程;但動(dòng)態(tài)方法難以完全掌握,使用時(shí)因?yàn)椴煌暮瘮?shù)或過(guò)程要定義很多很復(fù)雜的類(lèi)型和調(diào)用方法。對(duì)于初學(xué)者,筆者建議您使用靜態(tài)方法,待熟練后再使用動(dòng)態(tài)調(diào)用方法。

第五章 使用DLL的實(shí)用技巧 top

一、編寫(xiě)技巧。
1 、為了保證DLL的正確性,可先編寫(xiě)成普通的應(yīng)用程序的一部分,調(diào)試無(wú)誤后再?gòu)闹鞒绦蛑蟹蛛x出來(lái),編譯成DLL。

2 、為了保證DLL的通用性,應(yīng)該在自己編寫(xiě)的DLL中杜絕出現(xiàn)可視化控件的名稱(chēng),如:Edit1.Text中的Edit1名稱(chēng);或者自定義非Windows定義的類(lèi)型,如某種記錄。

3 、為便于調(diào)試,每個(gè)函數(shù)和過(guò)程應(yīng)該盡可能短小精悍,并配合具體詳細(xì)的注釋。

4 、應(yīng)多利用try-finally來(lái)處理可能出現(xiàn)的錯(cuò)誤和異常,注意這時(shí)要引用SysUtils單元。

5 、盡可能少引用單元以減小DLL的大小,特別是不要引用可視化單元,如Dialogs單元。例如一般情況下,我們可以不引用Classes單元,這樣可使編譯后的DLL減小大約16Kb。

二、調(diào)用技巧。
1 、在用靜態(tài)方法時(shí),可以給被調(diào)用的函數(shù)或過(guò)程更名。在前面提到的C++編寫(xiě)的DLL例子中,如果去掉extern ”C”語(yǔ)句,C++會(huì)編譯出一些奇怪的函數(shù)名,原來(lái)的TestC函數(shù)會(huì)被命名為@TestC$s等等可笑的怪名字,這是由于C++采用了C++ name mangling技術(shù)。這個(gè)函數(shù)名在Delphi中是非法的,我們可以這樣解決這個(gè)問(wèn)題:
改寫(xiě)引用函數(shù)為
function TestC(i:integer):integer;stdcall;
external ’Cpp.dll’;name ’@TestC$s’;
其中name的作用就是重命名。

2 、可把我們編寫(xiě)的DLL放到Windows目錄下或者Windows\system目錄下。這樣做可以在external語(yǔ)句中或LoadLibrary語(yǔ)句中不寫(xiě)路徑而只寫(xiě)DLL的名稱(chēng)。但這樣做有些不妥,這兩個(gè)目錄下有大量重要的系統(tǒng)DLL,如果您編的DLL與它們重名的話(huà)其后果簡(jiǎn)直不堪設(shè)想,況且您的編程技術(shù)還不至于達(dá)到將自己編寫(xiě)的DLL放到系統(tǒng)目錄中的地步吧!

三、調(diào)試技巧。
1 、我們知道DLL在編寫(xiě)時(shí)是不能運(yùn)行和單步調(diào)試的。有一個(gè)辦法可以,那就是在Run|parameters菜單中設(shè)置一個(gè)宿主程序。在Local頁(yè)的Host Application欄中添上宿主程序的名字就可進(jìn)行單步調(diào)試、斷點(diǎn)觀察和運(yùn)行了。

2 、添加DLL的版本信息。開(kāi)場(chǎng)白中提到了版本信息對(duì)于DLL是很重要的,如果包含了版本信息,DLL的大小會(huì)增加2Kb。增加這么一點(diǎn)空間是值得的。很不幸我們?nèi)绻苯邮褂肞roject|options菜單中Version選項(xiàng)是不行的,這一點(diǎn)Delphi的幫助文件中沒(méi)有提到,經(jīng)筆者研究發(fā)現(xiàn),只要加一行代碼就可以了。如下例:

library Delphi;

uses
SysUtils,
Classes;

{$R *.RES}
//注意,上面這行代碼必須加在這個(gè)位置

function TestDll(i:integer):integer;stdcall;
begin
Result:=i;
end;

exports
TestDll;

begin
end.

3 、為了避免與別的DLL重名,在給自己編寫(xiě)的DLL起名字的時(shí)候最好采用字符數(shù)字和下劃線(xiàn)混合的方式。如:jl_try16.dll。

4 、如果您原來(lái)在Delphi 1或Delphi 2中已經(jīng)編譯了某些DLL的話(huà),您原來(lái)編譯的DLL是16位的。只要將源代碼在新的Delphi 3或Delphi 4環(huán)境下重新編譯,就可以得到32位的DLL了。

[后記](méi):除了上面介紹的DLL最常用的使用方法外,DLL還可以用于做資源的載體。例如,在Windows中更改圖標(biāo)就是使用的DLL中的資源。另外,熟練掌握了DLL的設(shè)計(jì)技術(shù),對(duì)使用更為高級(jí)的OLE、COM以及ActiveX編程都有很多益處。

Delphi中如何調(diào)用DLL
馬上想得到的使用說(shuō)明有以下幾點(diǎn):

1. 所需動(dòng)態(tài)連結(jié)的 DLL 須置放在與執(zhí)行檔同一目錄或Windows System 目錄2. 確認(rèn) DLL export 出來(lái)的函式的原型, 以目前的情況而言, 通常只拿得到 C語(yǔ)言的函數(shù)原型,這時(shí)要注意 C 與 object Pascal 相對(duì)應(yīng)的型別, 如果需要, 在interface 一節(jié)定義所需的資料類(lèi)別

3. 在 implementation 節(jié)中宣告欲使用的函式, 語(yǔ)法大致如下:

procedure ProcName(Argu...); far; external ’DLL檔名’;

index n;

function FuncName(Argr...): DataType; far;

external ’DLL檔名’; index n;

宣告時(shí), index n 如果不寫(xiě), 便是參考資料中所謂 import by name 的方式, 此時(shí), 由於需要從 DLL 的 name table 中找出這個(gè)函式, 因此, 連結(jié)執(zhí)行速度比import by ordinal稍慢一些, 此外, 還有一種 by new name, 由於我沒(méi)用過(guò), 您可以查一參考資料, 大意是可以 import 後改用另一個(gè)程式命名呼叫這個(gè)函式

4. 然後, 呼叫與使用就與一般的Delphi 沒(méi)有兩樣5. 上述是直接寫(xiě)到呼叫DLL函式的程式單元中, 此外,也可以將DLL的呼叫宣告集中到一個(gè)程式單元(Import unit), Delphi 內(nèi)附的 WinTypes, WinProcs是一個(gè)例子,

您可以參考一下,同時(shí)觀察一下 C 與 Pascal 互相對(duì)應(yīng)的資料型態(tài)6. 除了上述的 static import 的方式, 另外有一種 dynamic import 的寫(xiě)法,先宣告一個(gè)程序類(lèi)型(procedural-type),程式執(zhí)行時(shí), 以L(fǎng)oadLibrary() API Load進(jìn)來(lái)後, 再以 GetProcAddress() API 取得函式的位址的方式來(lái)連結(jié)呼叫, 在ObjectPascal Language Guide P.132-133 有一個(gè)例子, 您可以參考看看

如果要舉個(gè)例子, 以下是從我以前的程式節(jié)錄出來(lái)的片斷:

(* for CWindows 3.1 *)

unit Ime31;

interface

uses

SysUtils, WinTypes, WinProcs, Dialogs;

type

(* 必要的資料型態(tài)宣告 *)

tDateNTime = record

wYear, wMonth, wDay: word;

wHour, wMin, wSec: word;

end;

TImePro = record

hWndIme: HWnd; { IME handle }

dtInstDate: tDateNTime; { Date and time of installation }

wVersion: word; { the version of IME }

szDescription: array[0..49] of byte; { Description of IME module}

szName: array[0..79] of byte; { Module name of the IME }

szOptions: array[0..29] of byte; { options of IME at startup}

fEnable: boolean; { IME status; True=activated,False=deactivated }

end;

pTImePro = ^TImePro;

function SetIme(const sImeFileName: string): boolean; far;

implementation

(* begin 呼叫 winnls.dll export 函數(shù)的宣告 *)

function ImpSetIme(hWndIme: HWND; lpImePro: pTImePro): boolean;far; external ’winnls.dll’;

(* end 呼叫 winnls.dll export 函數(shù)的宣告 *)

(* -------------------------------------------------- *)

(* SetIme(const sImeFileName: string): boolean;

(* ======

(* 切換到某一特定的輸入法

(*

(* 傳入引數(shù):

(* sImeFileName: 輸入法 IME 檔名, 例: phon.ime;

(* 空字串: 英數(shù)輸入法

(*

(* 傳回值:

(* True: 切換成功

(* False: 失敗

(* -------------------------------------------------- *)

function SetIme(const sImeFileName: string): boolean;

var

pImePro: pTImePro;

begin

Result := False;

if MaxAvail < SizeOf(TImePro) then

begin

MessageDlg(’記憶體不足’, mtWarning, [mbOk], 0);

Exit;

end

else

begin

New(pImePro);

try

if sImeFileName = ’’ then (* 空字串, 還原到英數(shù)輸入法 *)

pImePro^.szName[0] := 0

else

StrPCopy(@pImePro^.szName, sImeFileName);

Result := ImpSetIme(0, pImePro); (* 呼叫 ImpSetIme *)

finally

Dispose(pImePro);

end; { of try }

end;

end; { of SetIme }

end.

;

?

轉(zhuǎn)載于:https://www.cnblogs.com/xiongyingfeixiang/archive/2011/12/30/2307488.html

總結(jié)

以上是生活随笔為你收集整理的Delphi环境中编写调用DLL的方法和技巧的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。