发信人: redfox (Z掉了几乎所有的版...), 信区: BorlandDev
标  题: Delphi编程 -- 18.3 如何使用 DLL
发信站: 哈工大紫丁香 (2000年09月01日17:46:59 星期五), 站内信件

Delphi 如何使用 DLL 

请问如何用bc++ 制成 dll。可否用一个简单的例子说明..., 如果能指出是那本书
可参考更好...,又 delphi 如何call dll?

由於没有用 BC++ 写过 DLL(用 Delphi 倒是写了一个KeyPro保护DLL), 我想回
答 Delphi 如何使用 DLL 的这个部分.


这个 Topic 用是知道怎麽用, 不过要讲出来(甚至是键成文件), 就有点难了,以下的
说明如果写得不好, 还请各位网友指正:

马上想得到的使用说明有以下几点:

1. 所需动态连结的 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 < SizeOf(TImePro) then

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 }

 

--
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.227.107]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:5.063毫秒