Delphi 如何使用 DLL1. 所需动态连结的 DLL 须置放在与执行档同一目录或Windows System 目录
2. 确认 DLL export 出来的函式的原型, 以目前的情况而言, 通常只拿得到 C语言的函数原型,这时要注意 C 与 object Pascal 相对应的型别, 如果需要, 在interface 一节定义所需的资料类别
3. 在 implementation 节中宣告欲使用的函式, 语法大致如下:
procedure ProcName(Argu...); far; external 'DLL档名';
index n;
function FuncName(Argr...): DataType; far;
external 'DLL档名'; index n;
宣告时, index n 如果不写, 便是参考资料中所谓 import by name 的方式, 此时, 由於需要从 DLL 的 name table 中找出这个函式, 因此, 连结执行速度比import by ordinal稍慢一些, 此外, 还有一种 by new name, 由於我没用过, 您可以查一参考资料, 大意是可以 import 後改用另一个程式命名呼叫这个函式
4. 然後, 呼叫与使用就与一般的Delphi 没有两样
5. 上述是直接写到呼叫DLL函式的程式单元中, 此外,也可以将DLL的呼叫宣告集中到一个程式单元(Import unit), Delphi 内附的 WinTypes, WinProcs是一个例子,您可以参考一下,同时观察一下 C 与 Pascal 互相对应的资料型态
6. 除了上述的 static import 的方式, 另外有一种 dynamic import 的写法,先宣告一个程序类型(procedural-type),程式执行时, 以 LoadLibrary() API Load 进来後, 再以 GetProcAddress() API 取得函式的位址的方式来连结呼叫, 在Object Pascal Language Guide P.132-133 有一个例子, 您可以参考看看 
如果要举个例子, 以下是从我以前的程式节录出来的片断:
(* for CWindows 3.1 *)
unit Ime31;
interface
uses
SysUtils, WinTypes, WinProcs, Dialogs;
type
(* 必要的资料型态宣告 *)
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 函数的宣告 *)
function ImpSetIme(hWndIme: HWND; lpImePro: pTImePro): boolean;far; external 'winnls.dll';
(* end 呼叫 winnls.dll export 函数的宣告 *)
(* -------------------------------------------------- *)
(* SetIme(const sImeFileName: string): boolean;
(* ======
(* 切换到某一特定的输入法
(*
(* 传入引数:
(* sImeFileName: 输入法 IME 档名, 例: phon.ime;
(* 空字串: 英数输入法
(*
(* 传回值:
(* True: 切换成功
(* False: 失败
(* -------------------------------------------------- *)
function SetIme(const sImeFileName: string): boolean;
var
pImePro: pTImePro;
begin
Result := False;
if MaxAvail begin
MessageDlg('记忆体不足', mtWarning, [mbOk], 0);
Exit;
end
else
begin
New(pImePro);
try
if sImeFileName = ' then (* 空字串, 还原到英数输入法 *)
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. { of Unit Win31 }

解决方案 »

  1.   

    再加一篇
    都是收藏下来的,自己觉得还不错
    要调用DLL函数,需要知道确切的语法,然后设置一个函数类型。比如,在下例中,调用MyTest.DLL里面的CallMe函数。此函数接受两个整数作为参数,返回一个字符串。
    procedure TForm1.Button1Click(Sender: TObject);
     type TCallMeDll = function(a,b: Integer): string;
     var CallMeDll: TCallMeDll;
     FuncPtr: TFarProc;
     hDll: THandle;
     result: string;
     begin 
        hDll:=LoadLibrary('Mytestdll.dll');
        FuncPtr:=GetProcAddress(hDLL,'CallMe'); 
        @CallMeDll:=FuncPtr;
         if @CallMeDll <> nil then result:=CallMeDll(4,5);        FuncPtr:=nil; 
    FreeLibrary(hDll);
    end;
      

  2.   

    谢谢你的资料,可是那应该是调用DLL的方式吧,你能否给我讲讲入口函数和出口函数的原理啊