网络安全 频道

网吧电脑需要注意的五条防护技巧

  2.4 交互事件句柄系统

交互事件处理是PCB编辑器非常重要的部份。一个事件是一个在PCB编辑器中特殊的发生事情,并且一个代码段对那个特殊的发生事情进行响应,此响应代码是一个句柄,事件仅在交互模式下是句柄,也就是说,当一个十字光标被显示在PCB编辑器中时,交互事件句柄系统不处理用户事件,例如按下一个键来显示一个菜单等操作不被处理。

当PCB编辑器在交互模式下时,PCB事件被监视,如果一个事件发生,内置在PCB编辑器中的交互事件句柄系统起反应,代码段是对特殊事件起反应的句柄。在PCB编辑器中,对每一个不同的事件,它们有定义的句柄。


图4-7 事件句柄系统

    举一个例子,使用的事件句柄是一个由PCB API开发的,附加的、交互的PCB编辑器事件句柄,在PCB编辑器为交互模式时,此附加的使用外部事件句柄的系统来追踪事件,交互的尺寸在两个参考点间增加一个尺寸对象,用户点击PCB对象的第一点参考点和第二点参考点,一个尺寸对象接着被产生并且放置在当中。

 

PCB事件句柄的客户化提供了用户交互的精确控制,也就是说,当在交互模式下时,API使程序开发者能够连接他们的代码到指定的PCB编辑器的事件。

  3. PCB API的结构
  3.1 应用程序接口

在您编写一个外部的服务器前,您必须明白PCB编辑器提供的服务。这些服务有标准的协议,您的服务器必须使用。如果您要编写一个服务器,需使用PCB编辑器的服务,您必须首先明白用于连通PCB编辑器的协议。

协议被通过动态连接库技术(DLL)简化,一个DLL一旦加载到内存中就是一个应用程序,暴露一定固定数量的称为函数指针的函数入口点,这些功能指针针向DLL内部的函数和过程。PCB API为了其它服务器方便使用,提供了一个干净的接口,来封装函数指针到函数/过程接口。

PCB编辑器DLL文件为了任何外部服务器方便使用,提供了201个函数入口指针。PCB API是封装这些PCB编辑器函数入口指针的接口,给程序设计者使用PCB编辑器的输出过程和函数提供了访问手段。


图4-8 设计资源管理器的开放架构

 

自定义服务器的代码依赖于PCB编辑器的服务,必须访问PCB API文件,这些PCB API单元将允许服务器来使用通过PCB编辑器DLL所暴露的函数和过程,这些单元是PCBTypes、PCBProcs、PCBClass、SchProcs和SchClass。PCB API单元被内置在CSRTL.DPL中,CSRTL.DPL是当您在开发一个服务器时,您需要引用到服务器项目中的一个运行时间包,您仍然需要增加指定的单元到您的代码的Uses子句中。例如,客户化(外部)服务器通过引用三个PCB API单元有PCB API接口(参见图4-8),此服务器与PCB编辑器一道,被以插件方式加入到设计资源管理器中,因而它有访问PCB编辑器的能力。

  3.2 PCB API单元

AdvPCB.DLL文件提供了一个较大集合的过程和函数,过程和函数在运行时被激活。PCB API的任务是提供一个干净的接口,接口包裹在PCB编辑器的函数入口指针的周围。PCB API是一个层次结构,请见图4-9 PCB编辑器服务器,也就是说,AdvPCB.DLL是层次结构的顶层。下面被讨论的三个API单元构成整个PCB API,每一个单元将被详细讨论。

 


图4-9 PCB API单元

 

从图4-9中,PCB API单元PCBProcs、PCBClass和PCBTypes为PCB编辑器的PCB API提供了支持,客户化服务器通过PCB API与PCB编辑器协作,PCBTypes单元是PCB API最基本的单元,在PCB编辑器数据和一个外部的服务器数据之间提供了类型的兼容性支持。

 


图4-10 数据类型兼容
   

    例如,TReal(实数)类型在PCBTypes单元中被作为一个双精度(Double)类型定义,在32位Object Pascal中定义双精度为8位大小,如果您使用Object Pascal的实数类型来定义数据集,并且试图在PCB编辑器中使用TReal变量类型,此时如果您编译工程,编译器将产生一个错误。数据类型是非常重要的,在外部服务器中的数据块是8位长,且在PCB编辑器是数据块也是8位长,变量类型的大小必须相同。PCBTypes单元提供了预先定义的类型,很容易地使用,胜于您定义类型和检查数据类型值是否被使用。

 

    PCBPROCS单元通过使用地址指针和类型来包裹在这些函数周围,得到所有PCB编辑器服务器所暴露的过程和函数的地址。SetAllPCBProcAddresses API方法获取所有定义在PCB API中的函数和过程,所以外部服务器能提取出地址和进行类型转换,这些地址通过使用适当的类型转换作为正确的函数和过程,函数指针内存分配被API自动地完成,指针地址被设置到它的在PCB编辑器服务器的实现(implementation)处。

PCBClass单元提供了最高层水平的包裹,对象确定地址技术帮助隐藏和密封函数到对象中,因而PCBClass单元实现底层的例程。

  3.3 PCB API的实现

PCB API能帮助您来构建增强PCB和PCB库编辑器功能的服务器,您能检索有关印制板参数的信息,在它们上进行操作处理,并且您能为印制板设置新的参数,所以您能容易地构建一个服务,无须担心有关Windows句柄、编写有关参数检索的过程等等方面的麻烦。

过程SetAllPCBProcAddresses获取所有来自PCB编辑器的函数和过程的指针地址。

Procedure SetAllPCBProcAddreses;

Procedure SetProcAddress(var P : TFarProc; ProcName : Pchar);

Begin

If PcbLibrary = 0 Then P := Nil

Else P := GetProcAddress(PCBLibrary,ProcName);

//GetProcAddress是一个Windows API函数,其功能是获取指定的DLL模块中,某函数或功能地址,取出的地址放在P中。具体请见下面详细说明。

End;

Begin

PCBLibrary := GetModuleHandle(‘AdvPCB.DLL’);

// 如果一个指定的模块文件(DLL)已被映射到调用进程地址空间,GetModuleHandle函数返回此模块的句柄。

...

SetProcAddress(_PcbAPI_QueryPrimitive,’PcbAPI_QueryPrimitive’);

...

End;

GetProcAddress函数返回指定的输出动态连接库(DLL)中某函数的地址,定义如下:

FARPROC GetProcAddress(

HMODULE hModule,// handle to DLL moduleDLL模块的句柄

LPCSTR lpProcName // name of function函数名称

);

参数说明如下:

hModule

包含要获取函数指针的DLL模块的标识符,LoadLibrary或GetModuleHandle函数返回此句柄。

lpProcName

指向一个包含函数名称的以空终止符(null-terminated)为结尾的字符串,或指定函数的次序值。如果此参数是一个次序值,它必须是在低次序字,高次序字必须被置为零。

返回值:

如果此函数执行成功,返回值是DLL的输出函数的地址。如果函数执行失败,返回值是NULL。为得到扩大范围的错误信息,调用GetLastError。

注意:

GetProcAddress函数被用于检索在DLL中输出函数的地址,通过lpProcName指向的函数名称的拼写和大小写必须与在源DLL的模板中定义(.DEF)的文件中输出(EXPORTS)段的名称一致。

lpProcName参数能通过指定一个关联的在DLL的EXPORTS段中标识的次序值来标识DLL的函数,GetProcAddress在范围1到在.DEF文件中输出的最高次序值间校验指定的次序值,函数接着使用次序值作为索引来从一个函数表中读取函数的地址,如果.DEF文件从1到N(N是输出函数的数值)没有此函数的次序,一个错误将发生,GetProcAddress返回一个错误,空地址(non-NULL address),即这里没有指定次序的函数。

万一此函数也许不存在,使用名称比使用次序更好。

0
相关文章