快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

葡京娱乐场真人秀:第十章动态链接库编程(一)(2)



10.2.1.3 DLLs中的变量和段

一个DLLs拥有自己的数据段(DS),因而它声明的任何变量都为自己所私有。调用它的模块不能直接应用它定义的变量。要应用必须经由过程历程或函数界面才能完成。而对DLLs来说,它永世都没葡京娱乐场真人秀有时机应用调用它的模块中声明的变量。

一个DLLs没有自己的客栈段(SS),它应用调用它的利用法度榜样的客栈。是以在DLL中的历程、函数绝对不要假定DS = SS。一些说话在小模式编译下有这种假设,但应用Delphi可以避免这种环境。Delphi毫不会孕育发生假定DS = SS的代码,Delphi的任何运行光阴库历程/函数也都不作这种假定。需留意的是假如读者想嵌入汇编说话代码,毫不要使SS和DS登录同一个值。

10.2.葡京娱乐场真人秀1.4 DLLs中的运行光阴错和处置惩罚

因为DLLs无法节制利用法度榜样的运行,导致很难进行非常处置惩罚,是以编写DLLs时要十分小心,以确保被调用时能正常履行 。当DLLs中发生一个运行光阴错时,响应DLLs并不必然从内存中移去(由于此时其它利用法度榜样可能正在用它),而调用DLLs的法度榜样非常中止。这样造成的问题是当DLLs已被改动,从新进行调用时,内存中保留的仍旧可能是曩昔的版本,改动后的法度榜样并没有获得验证。对付这个问题,有以下两种办理措施:

1.在法度榜样的非常处置惩罚部分显式将DLL卸出内存;

2.完全退出Windows,而后从新启动,运行响应的法度榜样。

同一样平常的利用法度榜样比拟,DLL中运行光阴错的处置惩罚是很艰苦的,而造成的后果也更为严重。是以要求法度榜样设计者在编写代码时要有充分、殷勤的斟酌。

10.2.1.5 库初始化代码的编写

传统Windows中动态链接库的编写,必要两个标准函数:LibMain和WEP,用于启动和关闭DLL。在LibMain中,可以履行开锁DLL数据段、分配内存、初始化变量等初始化事情;而WEP在从内存中移去DLLs前被调用,一样平常用于进行需要的清理事情,如开释内存等。Delphi用自己特有的要领实现了这两个标准函数的功能。这便是在工程文件中的begin...end部分添加初始化代码。和传统Windows编程措施比拟,它的主要特色是:

1.初始化代码是可选的。一些需要的事情(如开锁数据段)可以由系统自动完成。以是大年夜部分环境下用户不会涉及到;

2.可以设置多个退出历程,退出时按顺序依次被调用;

3.LibMain和WEP对用户透明,由系统自动调用。

初始化代码完成的主要事情是:

1.初始化变量、分配全局内存块、登录窗口工具等初始化事情。在(10.3.2)节“使用DLLs实现利用法度榜样间的数据传输”中,用于数据共享的全局内存块便是在初始化代码平分配的。

2.设置DLLs退出时的履行历程。Delphi有一个预定义变量ExitProc用于指向退出历程的地址。用户可以把自己的历程名赋给ExitProc。系统自动调用WEP函数,把ExitProc指向的地址依次赋给WEP履行,直到ExitProc为nil。

下边的一段法度榜样包孕一个退出历程和一段初始化代码,用来阐明若何精确设置退出历程。

library Test;

{$S-}

uses WinTypes, WinProcs;

var

SaveExit: Pointer;

procedure LibExit; far;

begin

if ExitCode = wep_System_Exit then

begin

{ 系统关闭时的响应处置惩罚 }

end

else

begin

{ DLL卸出时的响应处置惩罚 }

end;

ExitProc := SaveExit; { 规复原本的退出历程指针 }

end;

begin

{DLL的初始化事情 }

SaveExit := ExitProc; { 保存原本的退出历程指针 }

ExitProc := @LibExit; { 安装新的退出历程 }

end.

在初始化代码中,首先把原本的退出历程指针保存到一个变量中,而后再把新的退出历程地址赋给ExitProc。而在自定义退出历程LibExit停止时再把ExitProc的值规复。因为ExitProc是一个系统全局变量,以是在停止时规复原本的退出历程是需要的。

退出历程LibExit中应用了葡京娱乐场真人秀一个系统定义变量ExitCode,用于标志退出时的状态。 ExitCode的取值与意义如下:

表10.1 ExitCode的取值与意义

━━━━━━━━━━━━━━━━━━━━━

取 值 意 义

—————————————————————

WEP_System_Exit Windows关闭

WEP_Free_DLLx DLLs被卸出

━━━━━━━━━━━━━━━━━━━━━

退出历程编译时必须关闭stack_checking,因而需设置编译唆使 {$S-} 。

10.2.1.6 编写一样平常DLLs的利用举例

鄙人面的法度榜样中我们把一个字符串操作的函数储存到一个葡京娱乐场真人秀DLLs中,以便必要的时刻调用它。应该葡京娱乐场真人秀留意的一点是:为了包管这个函数可以被其它说话编写的法度榜样所调用,作为参数通报的字符串应该是无停止符的字符数组类型(即PChar类型),而不是Object Pascal的带停止符的Srting类型。法度榜样清单如下:

library Example;

uses

SysUtils,

Classes;

{返回字符在字符串中的位置}

function InStr(SourceStr: PChar;Ch: Char): Integer; export;

var

Len,i: Integer;

begin

Len := strlen(SourceStr);

for i := 0 to Len-1 do

if SourceStr[i] = ch then

begin

Result := i;

Exit;

end;

Result := -1;

end;

exports

Instr Index 1 name 'MyInStr' resident;

begin

end.

您可能还会对下面的文章感兴趣: