DELPHI定义的条件编译的全部说明

合集下载

delphi类,自定义类的大体描述

delphi类,自定义类的大体描述

delphi类,自定义类的大体描述在Object Pascal中,定义类使用保留字class。

下面是类类型定义的语法格式: type<类型名>=class[(<基类型名称>)]<类成员列表>end;其中,选择使用基类型名称可以指出类的直接祖先类,类类型可以指定一个祖先类型,表示该类型是从这个指定的祖先类型继承下来的。

在Delphi中,如果不指明基类,则默认的父类为TObject类,也就是直接从TObject类派生出一个新类。

TObject类是在System单元中定义的。

例如,下面定义一个Student类:typestudent=classname:String[8];number:Integer;sex:(male,female);age:Integer;end;注意:与其他数据类型不同的是,类类型的定义只能出现在Program单元或Unit 单元最外层作用域的类型定义部分,而不能定义在变量说明部分或一个过程或函数内。

因此,类类型的作用域总是全局的。

2.类的字段可以看出,类型定义和记录类型定义很相似,但类类型可以有3类成员:字段、方法和属性。

类类型中的字段(field)也就是类的数据部分,其定义语法与记录中字段的定义语法相同,字段的类型可以是各种数据类型,甚至是另一个类类型。

上例中只定义了组成student类的4个字段。

3.类的方法方法(method)是在一个对象上执行指定操作的过程或函数。

方法的操作范围只能是对象内部的数据或对象可以访问的数据。

在类类型中声明的方法实际上是向前的定义,即在类定义中只定义方法的原型,而在程序的Implementation区进行对该方法的具体定义。

在定义方法时,可以直接使用类中已定义的字段,且访问时不需要引用限定符。

在调用方法时,Object Pascal隐含传递了一个参数Self,这个参数是一个指向输出方法的对象实例的指针,相当于C++里的This指针。

Delphi程序设计教程 第12章 编译调试应用程序

Delphi程序设计教程 第12章 编译调试应用程序

若编制的应用程序没有错误,程序的运行结果就 出现在屏幕上,可对其进行操作。若在编译的过程中 出现错误,则代码编辑器将光标放在包含出错位置的 行上,并在代码编辑器下方的框中显示错误的代码及 错误信息,如图12-2所示。 若错误可直接看出来,就可直接进行修改,然后 重新编译运行程序;若难于找出错误,就需要对程序 进行调试。 12.2.2 为应用程序提供运行参数 选择Run|Parameters命令,可打开运行参数对话 框,如图12-3所示。
(程序中的可执行行)。断点如图12-2所示。
12.1.3 监视 监视表达式可在单步或跟踪程序代码时,跟踪变 量或表达式的值。可以使用监视列表窗口查看当前设 置的监视表达式。 在单步调试程序时,监视表达式中的任何变量更 新时,监视表达式的值就发生变化;当程序的执行点 移动到变量没有定义的地方,则整个监视表达式的值 就是不确定的;当执行点又回到监视表达式可计算的 执行点时,则监视列表窗口中又显示出当前监视表达 式的值。 输入监视表达式后,使用监视列表窗口可以显示 当前表达式的值。
5. 暂停程序的执行 选择Run|Program Pause可以暂停程序的运行。 这时调试器暂停程序的执行,并将执行点放在要 执行代码的下一行。这时可以检查该位置上程序的状 态,然后继续执行或进行调试。 若程序在执行中,但不能返回到调试器中,可以
按Ctrl+Alt+Sys停止程序的运行(可能需要数次)。
5. 查找断点 断点设置后,在代码编辑器中是可见的(如图122所示)。若在代码编辑器中不可见的,则可以在断点 列表窗口中快速地查找断点。 在断点列表窗口的断点右单击,在出现的快捷菜 单上选择View Source命令,则代码编辑器就迅速地滚 动到该断点上(断点窗口仍保持激活);若选择Edit Source命令,则代码编辑器就迅速地滚动到该断点上, 并激活代码编辑器,可对程序进行编辑。

Delphi命名规范

Delphi命名规范

Delphi编程规范Delphi编程规范目录1 通用代码风格 (3)2 编程的规则 (4)3 函数与过程 (7)3.1 通用规范 (7)3.2 命名 (8)3.3 参数 (8)3.4 变量 (9)3.5 类型 (11)3.6 语句 (12)3.7 注释 (14)3.8 异常处理 (15)3.9 断言 (16)3.10 面向对象类 (17)4 文件 (18)5 控件(Components) (22)附录标准控件前缀 (23)Delphi编程规范1 通用代码风格一般来说,任何编程风格的目标都是清晰易懂,编码清晰化中最关键的一条就是保持一致性,无论使用什么风格,都要保证在整个项目中始终如一。

【规则1-1】代码的每级缩进为2个空格,由于制表符在不同的编辑器中的间隔不同,因此禁止在源代码中保存Tab制表符。

【规则1-2】行应当限制在80列以内。

超过80列的行应当被分成多个连续的行。

所有的后续行应当排列在该声明的第一行之后,并且缩进两个字符的空格。

说明:一般源代码每行的字符数不得超过80,除非只剩下一个单词。

如一行源代码超过了80个字符,可在逗号和操作符后面开始换行,并相对第一行缩进2个空格。

正例:function CreateWindowEx(dwExStyle: DWORD;lpClassName: PChar; lpWindowName: PChar;dwStyle: DWORD; X, Y, nWidth, nHeight: Integer;hWndParent: HWND; hMenu: HMENU; hInstance: HINST;lpParam: Pointer): HWND; stdcall;【规则1-3】各词法单位之间使用空格以增强程序的可读性。

说明:如a:=b应写成a := b【规则1-4】不同逻辑程序块之间要使用空行分隔。

说明:空行起着分隔程序段落的作用。

适当的空行可以使程序的布局更加清晰。

Delphi语言参考手册(4.0)

Delphi语言参考手册(4.0)

8.1 窗体Form6.1.1给MDI主窗口加背景在MDI程序中,由于MDI的主窗口一般的功能是提供子窗口显示的位置和提供菜单、工具条、状态条等,而窗口的客户区则一般不会有其它的用途,如果在这里画上一些软件的标志、公司的标志或者其它的背景图案的话,不仅可以使MDI的主窗口更加充实、美观,而且还可以更加突出公司的形象和增加公司标志在客户心中的地位。

由于MDI主窗口的特性,使用普通OnPaint和使用TImage等方法都不会产生作用。

下面将用编写一个简单的MDI程序来介绍如何实现。

第一步:打开Delphi(Delphi 1,2,3都可以),创建一个新的工程。

第二步:将Form1的FormStyle设置为fsMDIForm,设置成MDI的主窗口。

第三步:在Form1上增加一个Image元件,并选择要设置的背景到Image的Picture中。

第四步:在Form1的Private中定义:FClientInstance,FPrevClientProc : TFarProc;PROCEDURE ClientWndProc(V AR Message: TMessage);第五步:在实现(implementation)中加入上述过程的具体内容:PROCEDURE TForm1.ClientWndProc(V AR Message: TMessage);V ARMyDC : hDC;Ro, Co : Word;beginwith Message docase Msg ofWM_ERASEBKGND:beginMyDC := TWMEraseBkGnd(Message).DC;FOR Ro := 0 TO ClientHeight DIV Image1.Picture.Height DOFOR Co := 0 TO ClientWIDTH DIV Image1.Picture.Width DOBitBlt(MyDC, Co*Image1.Picture.Width, Ro*Image1.Picture.Height,Image1.Picture.Width, Image1.Picture.Height,Image1.Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);Result := 1;end;elseResult := CallWindowProc(FPrevClientProc, ClientHandle, Msg, wParam,lParam);end;第六步:在Form1的创建事件中加入:FClientInstance := MakeObjectInstance(ClientWndProc);FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));上面的步骤已经完成了MDI主窗口背景图案的设置,下面可以增加一个MDIChild窗口,实现MDI程序。

Delphi 第5章过程和函数解析

Delphi  第5章过程和函数解析
result := a + b; end;
第十页,编辑于星期五:十七点 四十五分。
重载过程或函数使用默认参数可能会导致二义性错误。 如:
function f1(a:integer; b:integer=10); overload; begin
result := a + b; end; function f1(a:integer):overload; begin
过程和函数的区别主要在于过程本身没有返回值,而函 数有一个返回值。另外,在定义过程时使用保留字 procedure,而定义函数使用保留字function。
第一页,编辑于星期五:十七点 四十五分。
一、过程和函数的声明
1. 过程声明 procedure 过程名(参数表); <局部声明部分> begin
需在冒号之后声明函数返回数据类型。局部声明部分 与过程的局部声明部分类似。 函数名本身作为一个特殊的变量,与系统预先定义的变 量Result一样,可在函数体中接受赋值,用来存储函 数返回值。
第三页,编辑于星期五:十七点 四十五分。
过程和函数首部中声明的参数称为形式参数,简称形参。 形式参数,以及过程和函数局部声明的各种标识符(如 常量、数据类型、变量、过程、函数等)均为局部的, 即它们的作用范围只在该过程或函数中,在局部范围内 有效。全局标识符是在主程序中定义的,其作用范围在 主程序和子程序。由于任一被调用的子程序中可以随意 地访问全局变量,全局变量的数据缺乏可靠和安全,因 此,应尽量避免在子程序中直接访问全局变量,而是通 过参数来传递外部数据,进行间接访问。
第四页,编辑于星期五:十七点 四十五分。
二、过程和函数调用
如同标准过程和函数的调用一样,程序中可以 调用自定义的过程和函数。过程调用的形式是以 其作为一条单独的语句。

delphi ifdef的用法

delphi ifdef的用法

delphi ifdef的用法题目:Delphi中括号条件编译指令(IFDEF)的用法引言:在Delphi编程语言中,作为一种过程化编程语言,通常需要针对不同的平台或版本进行软件的开发。

但是,不同的平台可能需要不同的代码或者代码选项,这就需要一种机制来根据条件来编译特定的代码段。

这时候,Delphi提供了一个非常有用的条件编译指令IFDEF。

本文将一步一步介绍Delphi中括号条件编译指令IFDEF的用法。

一、什么是IFDEF?IFDEF是一个用于在Delphi中根据条件编译代码块的指令。

它可以判断给定的符号(Symbol)是否被定义,如果被定义,则会编译指定的代码块,否则会跳过这段代码。

通过IFDEF指令,我们可以根据不同的条件来编译不同的代码,从而实现在不同平台或版本中使用不同的代码逻辑。

二、IFDEF的基本语法IFDEF指令的基本语法如下所示:{IFDEF Symbol}编译这里的代码块{ELSE}编译这里的代码块{ENDIF}其中,Symbol是我们自定义的符号,可以是预定义的符号,也可以是我们自己在代码中定义的符号。

如果Symbol被定义了,那么就会编译第一个代码块;否则,会编译第二个代码块。

三、IFDEF的实际应用1. 平台相关代码的编译在实际开发中,通常需要针对不同的平台编写不同的代码。

以Windows和Mac 为例,我们可以在不同的代码块中编写与平台相关的代码逻辑,如下所示:{IFDEF MSWINDOWS}Windows平台相关代码{ENDIF}{IFDEF MACOS}MacOS平台相关代码{ENDIF}通过IFDEF指令,我们只需要在编译时定义对应的符号(如MSWINDOWS或MACOS),就可以只编译对应平台的代码块,从而使得程序更加灵活和高效。

2. 不同版本代码的编译除了根据不同的平台来编译代码外,IFDEF指令还可以根据不同的版本来编译代码。

以Delphi 10.4版本为例,我们可以利用IFDEF指令实现在不同版本下使用不同的代码逻辑,如下所示:{IFDEF VER340}Delphi 10.4版本相关代码{ENDIF}通过IFDEF指令,我们可以根据不同版本的Delphi来编译相应版本的代码,以适应不同的开发环境和需求。

Delphi代码编写标准详解

Delphi代码编写标准详解

Delphi编写标准指南一、序言二、通用源代码格式规则2.1 缩格2.2 页边空格2.3 Begin...End 配对三、Object Pascal3.1 括号3.2 保留字和关键字3.3 过程和函数(例程)3.3.1 命名/格式化3.3.2 形式参数3.3.2.1 格式化3.3.2.2 命名3.3.2.3 参数的排序3.3.2.4 常量参数3.3.2.5 名称的冲突3.4 变量3.4.1 变量的命名和格式3.4.2 局部变量3.4.3 全局变量的使用3.5 类型3.5.1 大写约定3.5.1.1 浮点指针类型3.5.1.2 枚举类型3.5.1.3 变数和ole变数类型3.5.2 结构类型3.5.2.1 数组类型3.5.2.2 记录类型3.6 语句3.6.1 if 语句3.6.2 case 语句3.6.2.1 一般性话题3.6.2.2 格式3.6.3 while 语句3.6.4 for 语句3.6.5 repeat 语句3.6.6 with 语句3.6.6.1 一般话题3.6.6.2 格式3.7 结构异常处理3.7.1 一般话题3.7.2 try...finally的使用3.7.3 try...except的使用3.7.4 try...except...else的使用3.8 类类型3.8.1 命名和格式3.8.2 域3.8.2.1 命名/格式3.8.2.2 可视化3.8.3 方法3.8.3.1 命名/格式3.8.3.2 使用静态的方法3.8.3.3 使用虚拟/动态的方法3.8.3.4 使用抽象的方法3.8.3.5 属性存取方法3.8.4 属性3.8.4.1 命名/格式3.8.4.2 使用存取的方法四、文件4.1 工程文件4.1.1 命名4.2 窗体文件4.2.1 命名4.3 数据模板文件4.3.1 命名4.4 远端数据模板文件4.4.1 命名4.5 Unit文件4.5.1 通用Unit结构4.5.1.1 unit的名字4.5.1.2 uses子句4.5.1.3 interface部分4.5.1.4 implementation部分4.5.1.5 initialization部分4.5.1.6 finalization部分4.5.2 窗体单元4.5.2.1 命名4.5.3 数据模板单元4.5.3.1 命名4.5.4 一般目的单元4.5.4.1 命名4.5.5 构件单元4.5.5.1 命名4.6 文件头五、窗体和数据模板5.1 窗体5.1.1 窗体类型命名标准5.1.2 窗体实例命名标准5.1.3 自动创建窗体5.1.4 模式窗体实例化函数5.2 数据模板5.2.1 数据模板命名标准5.2.2 数据模板实例命名标准六、包6.1 使用运行包和设计包的比较6.2 文件命名标准七、构件7.1 用户自定义构件7.2 构件单元7.3 使用注册单元7.4 构件实例命名约定7.5 构件的前缀7.6 Standard页7.7 Additional页7.8 Win32页7.9 System页7.10 Internet页7.11 Data Access页7.12 Data Controls页7.13 Decision Cube页7.14 QReport页7.15 Dialogs页7.16 Win3.1页7.17 Samples页7.18 ActiveX页7.19 Midas页一、序言本文档详述了在Delphi 4开发者指南下进行编程的代码编写标准。

Delphi7.0 预编译指令说明

Delphi7.0 预编译指令说明

Extended Syntax: 扩展语法开关。他能允许或禁止Delphi的扩展语法。对于函数调用和Null结束字符串的使用规定。
缺省:{$X+}{$EXTENDEDSYNTAX ON}
注:向后兼容,已不使用。
Typed @ Operator: 类型化的@运算符检查。应用于局部的变量引用上,控制@运算符返回的指针值类型。@(等价于Addr)是否得到有类型指针
如果{$H+}或{$LONGSTRINGS ON},string类型为AnsiString,长度>255。
如果{$H-}或{$LONGSTRINGS OFF},string类型为ShortString,长度<=255。
缺省:{$H+}{$LONGSTRINGS ON}
Assignable Typed Constants: 可分配类型常量,是否可以修改有类型常量的值。用于向下与Delphi 1.0兼容。
I := 2;
end;
如果{$O-}或{$OPTIMIZATION OFF},如下
var
I: Integer;
begin
I := 1; //被编译,也就是说调试的时候,这行有断点
I := 2;
end;
缺省:{$O+}{$OPTIMIZATION ON}
Stack frames: Windows 堆栈帧。其作用域是局部的,他使编译器成为远端过程和函数生成特定的开头和
结尾代码。这个指令用于Windows 3.0的实模式,对所有Delphi应用程序他应该是关闭的,一些调试工具
需要此类信息。
如果{$W+}{$STACKFRAMES ON},强制每个过程或函数生成堆帧,查找错误时,编译器需要堆帧帮忙。

Delphi编译器、编译指令、条件编译指令(预编译指令)

Delphi编译器、编译指令、条件编译指令(预编译指令)

Delphi编译器、编译指令、条件编译指令(预编译指令)Delphi 编译器、编译指令、条件编译指令(预编译指令)⼤部分情况下Delphi不需要⼲涉 Object Pascal 编译器的运⾏,但是有时也需要对编译器进⾏必要的设置。

1、编译器设置对话框编译器的编译指令是⽤于指定编译器对项⽬编译过程的动作和⾏为。

可以通过[Project]->[Options]->[Complier]选项页进⾏设置,绝⼤部分的编译环境都可以通过这⼀对话框进⾏调整,他包含了对代码、语法、调试信息等的设置。

1.1、代码设置(Code Generation) 代码⽣成Optimization: 代码优化开关Aligned record fields: 字对齐数据。

//这个编译指令能够在变量和类型化常量的字节对齐和字对齐之间进⾏切换,其作⽤是全局的。

Stack frames: Windows 堆栈帧。

//其作⽤域是局部的,他使编译器成为远端过程和函数⽣成特定的开头和结尾代码。

这个指令⽤于Windows 3.0的实模式,对所有Delphi应⽤程序他应该是关闭的。

Pentium-safe FDIV: Pentium安全FDIV检查。

//此指令能够在Pentium处理器中指定编译器是否创建能够检测和使⽤有缺陷的浮点除法指令的代码。

1.2、运⾏期错误(Runtime Errors)Range Checking: 范围检查。

//这个指令的作⽤范围是局部的,⽤于控制范围检验代码的⽣成。

I/O Checking: I/O检查。

//这个指令的作⽤域为局部,⽤来⽣成对⼀个⽂件的输⼊和输出过程和调⽤结果进⾏检查的代码。

⼀般应该使其功能打开。

Overflos Checking: 溢出检查。

//其作⽤是⽣成对算术溢出检查的代码。

1.3.语法设置(Syntax Optings) 语法选项Strict Var- strings: 静态变量串开关。

Delphi开发要求规范

Delphi开发要求规范

Delphi开发规一、Delphi版本统一使用Delphi2007进行项目开发、小部分模块(比如:系统构子模块Dll、Delphi2007编译出问题的功能)可以使用Delphi7开发Dll文件,供Delphi2007编写的主程序调用。

当需要Delphi2007以上版本进行开发时,必须要满足使用Delphi新特性才能完成新功能的条件。

二、Delphi插件统一使用以下2款Delphi第三方插件来提高工作效率。

1)CnWizards 是一组集成在 Delphi / C++ Builder 的 IDE 中,用于增强 IDE 功能、提高 IDE 的可用性及开发效率的免费、开放源码工具。

2)Delphi2007以下版本:DelForExp 是一款Delphi代码格式化工具。

该工具重点设置如下图:缩进空格数必须为4。

三、一般格式规1.缩进统一使用 4 个空格缩进。

参照下图进行设置:把Tab的空格数设置为4,以后一按tab键可以一次缩进4个空格。

2. Begin..Endbegin 语句和 end 语句在源程序中要独占一行,例如:for I := 0 to 10 do begin //不正确的用法end;for I := 0 to 10 do //正确的用法 begin end;3.空格在操作符及逻辑判断符号的两端添加空格,例如:I := I + 1;,a and b 等,但添加括号时不需要空格。

例如:if ( a > b ) then //错误的用法If (a > b) then //正确的用法又例如:procedure Test(Param1: integer; Param3: string);4.过程和函数1)命名及格式过程和函数的名称应全部使用有意义的单词组成,并且所有单词的第一个字母应该使用大写字母。

例如:procedure formatharddisk;//不正确的命名procedure FormatHardDisk;//正确的命名设置变量容的过程和函数,应使用 Set 作为前缀,例如: Procedure SetUserName;读取变量容的过程和函数,应使用 Get 作为前缀,例如:Function GetUserName:string;2)注释1)、除控件产生的事件以外的自定义函数都必须加入以下格式的注释。

Delphi命令行编译指南

Delphi命令行编译指南

Delphi命令行编译指南Borland出品的Delphi,有着闪电般的编译速度,但是在界面控件使用较多、工程项目较大的时候,编译一个工程仍需要一段时间,打开庞大的Delphi IDE,也需要时间。

其实,在一个工程开发结束,调试完成之后的Release编译,完全可以用命令行来执行,因为Delphi的编译器参数不像C++编译器那样复杂。

笔者把Delphi联机手册中关于命令行编译(command-line compiler)的几篇主题作了翻译,希望对Delphi开发人员有帮助。

目录1Command-line compiler命令行编译器2Command-line compiler options命令行编译选项3Compiler directive options编译器指令选项4Compiler mode options编译模式选项5DCC32.CFG file DCC32.CFG配置文件6Debug options调试选项7Directory options目录选项8IDE command-line options IDE命令行选项9Generated files几个IDE自动产生的文件介绍1Command-line compiler命令行编译器Delphi's command-line compiler (dcc32.EXE) lets you invoke all the functions of the IDE compiler (DELPHI32.EXE) from the DOS command line (see IDE command-line options. Run the command-line compiler from the DOS prompt using the syntax:Delphi’s命令行编译器(dcc32.exe)允许你从DOS命令行方式(参照:IDE命令行选项)实现IDE编译器(delphi32.exe)的所有功能。

Delphi法使用说明

Delphi法使用说明

德尔菲评价法德尔菲是Delphi的中文译名。

Delphi原是一处古希腊遗址,是传说中神渝灵验,可以预卜未来的阿波罗神殿的所在地。

德尔菲(Delphi)法是美国“兰德”公司于1966年首先用于技术预测的。

美国空军委托成立不久的的“兰德”公司从事一项有关如何利用专家意见的研究工作,即以德尔菲为代号的“德尔菲计划”,是—项有关如何合理和有效地利用专家意见和专家判断的研究计划。

“兰德”公司的数学家赫尔默和他的同事多尔基研究出了一种调查和分析专家意见的有效方法:通过简单扼要的专家意见征询表,征求一组专家的意见,经过有控制的反馈,取得尽可能可靠的统一意见。

他们把这种方法命名为德尔菲法。

德尔菲法是专家会议预测法的一种发展。

它在很大程度上克服了一般专家会议存在的种种缺陷,发扬了专家会议的许多长处。

在上世纪六十年代末到七十代中,获得了广泛的应用,它在各类预测方法中所占比重为24.2%。

德尔菲方法的出现,标志着直观预测方法的进步和发展。

第一节德尔菲法的特点与应用一、德尔菲法的特点为了弥补专家会议的缺点和不足,德尔菲有如下三个特点。

(一)匿名性为克服专家会议易受心理因素影响缺点,德尔菲法采用书信方式,进行匿名性的意见征询,参加应答的专家互不见面,互不了解其他专家的答复情况。

专家可以充分发表自然意见或修改自己意见无需作公开说明,而不必担心损害自己的威望。

(二)轮间反馈性德尔菲法不同于民意测验,一般要经过四轮,民意测验只进行一轮,没有反馈性。

德尔菲法在每一轮意见征询之后,要将征得的专家意见进行统计处理,汇总并将处理汇总所得的结果反馈结每位专家.作为其提出下一轮预测的参考。

(三)统计性统计性是德尔菲法不同于专家预测法的一个重要特征。

它采用统计方法,对专家的集体预测结果进行定量评价和处理。

二、德尔菲法的基本程序在德尔菲法实施的第一轮开始之前,必须事先作好准备工作,例如阐明专家组所要预测的课题领域,解释将使用的方法等。

做好准备工作之后,德尔菲法将按如下程序进行。

Delphi中的包(一):关于exe的编译、连接和执行.net-电脑资料

Delphi中的包(一):关于exe的编译、连接和执行.net-电脑资料

Delphi中的包(一):关于exe的编译、连接和执行.net-电脑资料首先把需要分析的问题列出来:什么是包?什么是exe?它们在组成上有什么不同?包跟dcu是什么关系?dcp是干什么的?这些文件在编译时是什么关系?又是怎么装载的?装载了以后怎么样操作包?dll可以exports,但是为什么delphi帮助中不提包的exports,但是有些首先把需要分析的问题列出来:什么是包?什么是exe?它们在组成上有什么不同?包跟dcu是什么关系?dcp是干什么的?这些文件在编译时是什么关系?又是怎么装载的?装载了以后怎么样操作包?dll可以exports,但是为什么delphi帮助中不提包的exports,但是有些代码却又在包中使用exprots?首先来看看delphi的编译过程,。

delphi的工程中有两类:包和程序,前者的后缀为dpk,后者为dpr。

从简单的开始,先来搞dpr。

根据delphi的帮助文档,一个典型的dpr文件的结构如下:1 program Editor;23 uses4 Forms, {change to QForms in Linux}5 REAbout in 'REAbout.pas' {AboutBox},6 REMain in 'REMain.pas' {MainForm};78 {$R *.res}910 begin11 Application.Title := 'Text Editor';12 Application.CreateForm(TMainForm, MainForm);13 Application.Run;14 end.其中10行到14行,begin…end很自然就是程序的执行入口。

uses部分指明了程序需要使用的一些Unit,这个就比较含糊了,为什么有的会用in指明源代码的位置(这部分是自己向工程中添加的),有的如Forms这个部分,却又不需要?那每个Unit又会uses其它Unit,这个问题似乎越来越复杂了。

DELPHI定义的条件编译的全部说明

DELPHI定义的条件编译的全部说明

DELPHI定义的条件编译的全部说明经常看到一些程序里面用到如:{$ifdef win16},{$ifdef win32}之类的信息,可是这些好像并没有定义,不知道在哪里可以找到这些条件编译的定义或者是说明具体讲述win16代表什么,WIN32代表什么,VER140。

代表什么的?{$IFDEF WIN32} -- 这可不是批注喔!对于Delphi来说﹐左右大括号之间的内容是批注﹐然而「{$」(左括号后紧接着货币符号)对于Compiler(编译器)而言并不是批注﹐而是写给Compiler看的特别指示。

应用时机与场合Delphi中有许许多多的Compiler Directives(编译器指令)﹐这些编译指令对于我们的程序发展有何影响呢? 它们又能帮我们什么忙呢?Compiler Directive 对程序开发的影响与助益, 可以从以下几个方向来讨论:?协助除错? 版本分类?程序的重用与管理? 设定统一的执行环境协助除错稳健熟练的程序设计师经常会在开发应用系统的过程中﹐特别加入一些除错程序或者回馈验算的程序﹐这些除错程序对于软件品质的提升有极其正面的功能。

然而开发完成的正式版本中如果不需要这些额外的程序的话﹐要想在一堆程序中找出哪些是除错用的程序并加以删除或设定为批注﹐不仅累人﹐而且容易出错﹐况且日后维护时这些除错程序还用得着。

此时如果能够应用像是$IFDEF的Compiler Directives ﹐就可以轻易的指示Delphi要/不要将某一段程序编进执行文件中。

同时﹐Compiler本身也提供了一些错误检查的开关﹐可以预先对程序中可能的问题提醒程序设计师注意﹐同样有助于撰写正确的程序。

版本分类除了上述的除错版本/正式版本的分类之外﹐对于像是「试用版」「普及版」「专业版」的版本分类﹐也可以经由Compiler Directive的使用﹐为最后的产品设定不同的使用权限。

其它诸如「中文版」「日文版」「国际标准版」等全球版本管理方面﹐同样也可以视需要指示Delphi 特别连结哪些资源档或者是采用哪些适当的程序。

DELPHI定义的条件编译介绍说明

DELPHI定义的条件编译介绍说明

delphi反编译:DELPHI定义的条件编译介绍说明疯狂代码 / ĵ:http://Delphi/Article66671.html经常看到些里面用到如:{$def win16},{$def win32}的类信息可是这些好像并没有定义不知道在哪里可以找到这些条件编译定义或者是介绍说明具体讲述win16代表什么WIN32代表什么VER140代表什么?{$IFDEF WIN32} — 这可不是批注对于Delphi来说﹐左右大括号的间内容是批注﹐然而「{$」(左括号后紧接着货币符号)对于Compiler(编译器)而言并不是批注﹐而是写给Compiler看特别指示应用时机和场合Delphi中有许许多多Compiler Directives(编译器指令)﹐这些编译指令对于我们发展有何影响呢? 它们又能帮我们什么忙呢?Compiler Directive 对开发影响和助益, 可以从以下几个方向来讨论:?协助除错? 版本分类?重用和管理? 设定统执行环境协助除错稳健熟练设计师经常会在开发应用系统过程中﹐特别加入些除错或者回馈验算﹐这些除错对于软件Software品质提升有极其正面功能然而开发完成正式版本中如果不需要这些额外话﹐要想在堆中找出哪些是除错用并加以删除或设定为批注﹐不仅累人﹐而且容易出错﹐况且日后维护时这些除错还用得着此时如果能够应用像是$IFDEFCompiler Directives ﹐就可以轻易指示Delphi要/不要将某段编进执行文件中同时﹐Compiler本身也提供了些检查开关﹐可以预先对中可能问题提醒设计师注意﹐同样有助于撰写正确版本分类除了上述除错版本/正式版本分类的外﹐对于像是「试用版」「普及版」「专业版」版本分类﹐也可以经由Compiler Directive使用﹐为最后产品设定区别使用权限其它诸如「中文版」「日文版」「国际标准版」等全球版本管理方面﹐同样也可以视需要指示Delphi特别连结哪些资源档或者是采用哪些适当以上两则例子中﹐各版本间只需共享同份代码即可Delphi 1.0 和 Delphi 2.0有许多区别的处﹐组件资源文件(.DCR)即是其中例﹐两者档案格式并不兼容﹐在您读过本文的后﹐相信可以写出这样﹐指示Delphi在区别版本采用适当资源文件以利于组件安装{$IFDEF WIN32}{$R XXX32.DCR}{$ELSE}{$R XXXX16.DCR}{$EDNIF}重用和管理经过前文讨论后﹐相信你已经不难看出Compiler Directives在管理上应用价值对于原始重用和管理﹐也是Compiler Directives 使得上力地方. 举例来说: Pascal-Style串是Delphi 1.0和 Delphi 2.0的间明显差异﹐除了原先短串的外﹐Delphi 2.0的后还多了更为方便使用长串﹐同时﹐系统也额外提供了像是 Trim这样串处理函式假如您有个串处理单元必须要同时应用于Delphi 1.0 和2.0项目时﹐编译指示器可以帮你忙此外﹐透过像是{$I xxxx} 这样 Compiler Directives﹐我们也可以适当含入某些, 同样有助于切割组合我们或编译设定设定致执行环境项目小组成员间﹐必须有共同环境设定﹐我很难预料个小组成员间彼此有区别{$B}{$H}{$X}设定﹐最后子系统在并入主时会发生什么事此外, 当您写好个组件或单元需要交予第 3者使用时, 使用编译指示器也可以保证元件使用者和您有相同编译环境使用Compiler Directives指令语法Compiler Directives从外表看起来和批注颇为类似, 和批注区别是:Compiler Directives语法格式都是以「{$」开始, 不空格紧接个名称(或个字母)表明给Compiler特别指示, 再加上其它开关或参数内容, 最后以右大括号作为指令结束, 例如:{$B+}{$R-}{$R MyCursor.res}同时, 就如同Pascal变量名称和保留字样, Compiler Directives也是不区分大小写从指令语法格式来说Compiler Directives﹐可以进步分类成以下 3种格式:?开关指令(Switch directives)这类指令都是单字母以不空格方式连接「+」或「-」符号; 或者是开关名称以个空格后连接「ON」或「OFF」来表示作用/关闭某个编译指示开关例如:{$A+}{$ALIGN _disibledevent=>Re(F);CloseFile(F);{$I+}FileExists := (IOResult = 0) and (FileName <> ‘’);end; { FileExists }可移植性我们都可能会用到其它公司或个人创作unit或component, 也可能分享给其它人, 换句话说, 单元或可能会在区别机器上编译, 直接将Compiler directives加入, 不仅可以免去使用前需要特别更改IDE麻烦, 更重要是解决了各个单元间要求区别编译环境歧异注意事项Compiler directives作用和影响范围如同变量可见范围和生命周期, 在我们使用 Compiler Directives 时也必须注意各个Compiler Directives 作用范围.Compiler Directives作用范围可分为以下两种:全域全域Compiler Directives, 影响所及是整个项目; 我们稍早前提到经由Delphi IDE改变Compiler directives方式就属于全域设定区域而区域Compiler Directives 影响所及只从Compiler Directives 改变那行开始, 直到该单元(Unit)结束或另个相同Compiler Directives 为止,对其他单元并没有影响也就是说, 如果在unit中特别加入Compiler directives, Compiler会优先采用区域设定, 然后才是属于项目层级全域设定值得提是, 在中直接加入Compiler directives最大作用范围也只限于当时那个单元而已, 对其他单元并没有任何影响, 即使是以uses参考也是样也就是说,我们可以透过uses参考其它unit公开变量和函式, 但是各个unit编译指令并不会互相参考这项独立性质, 使得unit的间编译环境设定和关系变得十分简洁, 例如Delphi 2.0VCL都是在{$H+}情况下编译,因此, VCL中串都是以长串型态编译而成, 有了这项编译指令独立特性, 不论我们Prject中设定为何, 这些在VCL中定义过串都是长串我们Project也不会uses了VCL中unit而改变了自己设定因此, 在我们移交到网络上时, 大可以放心在中加入必要Compiler directives, 别担心, 即使别unit以uses参考了我们, 也不影响它自己原来设定如果我们自行以{$DEFINE _DEBUGVERSION}($DEFINE在稍后个别指令介绍中将有介绍说明)定义了个条件符号, 这个新条件符号也是区域, 换句话说, 它只从定义那个单元那列的后才成立, 当然, 也只对目前这个单元有效. 由于自订条件符号只有区域作用, 如果有好几个单元都需要参考到某个条件符号, 如何办呢? 嗯! 在每个单元开头处中都加上编译指示是最直接方式,可是略嫌麻烦, 特别是编译指示有变时, 要修正各个单元设定内容, 很容易疏忽而出错比较简易可行作法是从Delphi IDE整合发展环境主选单-Project / Options / Directories/ConditionalConditionals 中填入条件名称这样, 相对于项目各个unit而言, 就有了个全域条件符号 或者, 您也可以参考本文对于{$I}这个Compiler Directive介绍说明我在那里指出了另个弹性解决方式修改过编译指令后, 建议BuildAll过次请试试这个:procedure TForm1.Button1Click(Sender: TObject);begin// opt是用来侦测某个编译开关作用状态{$opt H+}ShowMessage(’H+’);{$}ShowMessage(’H-’);{$end}end;在我们执行上述时, 在Delphi预设是$H+时, ShowMessage会在画面上会显示「H+」, 执行过后, 让和form内容和位置保留不变, 单纯从主选单: Project/Options/Compiler, 将Huge Strings核对方块清除($H-),然后按下F9执行, 咦! 如何还是看到「H+」?!那是Delphi只会在unit内容经过异动后才会重新将.PAS编译成.DCU, 在我们例子中, 并没有变动, .DCU当然也没有重新产生, 最后.EXE这个部分自然也是没什么变化所以, 要解决这个问题,只要以Delphi IDE主选单Project/Build All指示Delphi重新编译全部即可因此, 如果您从Delphi IDE修改过Compiler Directives后, 记得要Build All喔!不应该用来作为执行流程控制在中, 我们可以使用叙述, 根据执行当时情况控制执行时流程, 但我们不可以用{$IFDEF}来作同样事, 为什么? 从上述介绍说明, 相信您不难发现, Compiler directives会对最后.EXE内容发生直接影响, 应用像是{$IFDEF}指示Compiler结果, 几乎可以视同授权Compiler在编译那个时候自动选用/舍弃到.DCU, .EXE中, 换句话说, 在编译完成时, 会执行到那段已成定局了,我们自然不能用它来作流程控制条件编译巢套最多可以16层在使用{$IFDEF}…{$ENDIF}条件编译我们时, 个{$IFDEF}中可以再包含另个{$IFDEF}, 但深度最多只能16层, 虽然是个限制, 但以正常情形来说, 这应该已经足够了有些Compiler directives不应写在Unit中对于像是{$MINSTACKSIZE}{$MAXSTACKSIZE}管理堆栈大小, 或者像是{$APPTYE}指示编译成图形/文字模式Compiler directives, 只能写在.DPR中, 写在Unit中是没有效果建议事项确定您了解指令影响由于编译指令影响是如此直接和深远, 在修改和应用某个Compiler directive时,请确定您已经了解其含意和影响打开全部侦错开关Delphi有关侦错Compiler directives如下:? $HINTS _disibledevent=>ByteField: ;IntegerField: eger;end;…procedure TForm1.Button1Click(Sender: TObject);beginShowMessage(IntToStr(SizeOf(MyRecord)));end;ShowMessage在{$A+}时显示结果是:「8」; 倘若是{$A-}, 那所得结果是「5」,按理说, Byte应该只要个就足够了, 但是考虑到硬件执行特性, 经过对齐后record会有比较好执行速度有关这个Compiler Directive要注意事项是: 不管{$A}开关是ON或OFF, 使用packed修饰过记录宣告, 是定不会对齐. 例如:MyRecord = packed record // 不会对齐记录宣告方式{$APPTYPE GDI} 应用型态般情形下, Delphi会以{$APPTYPE GUI}方式产生个图形使用者接口, 如果您需要产生个文字屏幕模式, 那可以经由:在.DPR中加入{$APPTYPE CONSOLE}从主选单: Project/Options/Linker/EXE and DLL Options, 核取「Generate Console Application」Check Box其它有关这个Compiler Directive注意事项有:$APPTYPE不能应用在DLL项目或单单元(Unit), 它只对.EXE有意义而且只有写在.DPR中才有作用我们可以应用单元中IsConsole在执行时侦测应用类型参阅Object Pascal手册第十 3章可以知道更多有关Console Mode Application信息{$B-} 布尔评估请看以下:(Length(sCheckedDateString) <>or EmptyStr(sCheckedDateString)or (sCheckedDateString = ‘ . . ‘)or (sCheckedDateString = ‘ / / ‘) thenbeginResult := True;Exit;end;假如sCheckedDateString串内容是「85/12/241」(长度9)话, 以上述句, 其实在第个逻辑判断时就已经知道结果了, 即使不看后来逻辑运算结果也知道整个式子会是真值假如您希望对整个逻辑表达式进行完整评估 — 尽管结果已知, 后来逻辑运算也不影响整个结果时仍要全部评估过, 请将这个Compiler directives设为{$B+}, 反的, 请设为{$B-}, 系统默认值是{$B-}{$D+} 除错信息当以{$D+}(默认值)编译时, 我们可以用Delphi整合发展境境Debugger设定断点, 也可以使用Trace Into或Trace Info追踪执行过程, 值得注意是, 以{$D+}编译, 执行速度并不会受到影响, 只不过编译过DCU档案长度会加大, 但EXE档大小不变{$DEFINE条件名称} 定义条件名称随着您对Compiler Directives了解和应用程度加深, 您会发现这是个非常实 用编译指示经常, 我们会除错需要﹑区别区别版本等缘故, 希望选择性采用或排除某段, 这个时候, 我们就可以先以$DEFINE定义好个条件名称(Conditional name),然后配合{$IFDEF条件名称}…{$ELSE}…{$ENDIF}指示编译器按指定条件名称的有无来选择需要编译以下列片断来说:{$DEFINE _ProVersion}…procedure TForm1.Button1Click(Sender: TObject);begin{$IFDEF _Proversion}frmPr.ShowModal; // A{$ELSE}ShowMessage(’很抱歉, 试用版不提供打印功能’);{$ENDIF}end;编译器将会选择编译上述A那列, 日后, 如果我们需要编译「简易版」版本时, 只要将{$DEFINE _ProVersion}那列整个删掉或者, 将{$DEFINE _ProVersion}改成{-$DEFINE _ProVersion},让它变成普通批注或者, 在{$DEFINE _ProVersion}下列加上{$UNDEF _ProVersion},解除_ProVersion这个条件名称定义这样, 由于_ProVersion这个条件名称未定义缘故, Compiler就只会选择{$ELSE}下那段, 重新编译次, 不需费太多力气, 很容易就可以制作出简易版」了, 省去了要同时维护两份麻烦使用$DEFINE时其它注意事项如下:以{$DEFINE}定义条件名称都是区域换句话说, 它作用范围只在当时所在单元才有效, 即使定义在uniterface, 由其它unit以uses参考也没有效,仍然只有在目前unit有作用此外, 它作用范围是从定义起, 到unit结尾或者以{$UNDEF}解除为止如果单元中已经用{$DEFINE}定义了个条件名称, 而且也没有用{$UNDEF}解除定义, 重新{$DEFINE}个同样名称并没有作用, 换句话说, 它们是同个.假如需要个全域条件名称, 您可以:主选单: Project / Options / Directories/Conditional Conditionals 中填入条件名称以下标准条件名称, 是Delphi 2.0已经预先预备好, 我们可以直接引用,同时, 它们都是全域, 任何Unit都可以参照得到VER90: Delphi Object Pascal版本编号90表示9.0版, 日后若出现9.5版时, 也会有VER95定义 WIN32: 指出目前是在Win32(95, NT)作业环境? CUP386: 采用386(含)以上CPU时, 系统会提供本条件名称? CONSOLE: 此符号会于应用是在屏幕模式下编译时才定义{$DESCRIPTION 描述内容}应用{$DESCRIPTION}可以指定加入段文字到.EXE或.DLL表头模块描述进入点(module description entry)中﹐通常我们会用这个Compiler Directive加入应用名称和版本编号到.EXE中例如:{$DESCRIPTION Dchat Version 1.0}{$X+} 扩充语法这是为了和的前Pascal版本前向兼容编译指令, 虽然设定这个开关型指令仍有作用, 但笔者建议您大可保留系统默认值{$X+}, 在{$X+}下:? 不需要非得准备个变量接受传回值, 换句话说, 传回值可以舍弃, 此时, 就可以像是呼叫样, 很方便呼叫? 支持Pchar型态和零基作为C语言以Null结尾串{$HINTS OFF} 提示讯息打关{$HINTS}开关后, Compiler会提示设计师注意以下情况:? 变量定义了却没有使用? 流程中不会执行for或while循环? 只有存入没有取用指定叙述意思是说, 指定数据到某个变量的后,却没有任何参考取用这个变量值{$HINTS _disibledevent=>varI, J: eger;begin_False thenfor I := 1 to 3 do ;J := 3;end;{$HINTS OFF}由于简单, 在两个$HINTS中间, 我们不难看出:? for循环不会执行到, I变量也因此不曾用过? J := 3写了等于白写但在越写越长而日趋复雓时, 藉由{$HINTS _disibledevent=>举例来说, 笔者有份由Keypro厂商提供.OBJ檔, 在使用时, 相关如下:…{$L hasptpw.obj}{$F+}procedure hasp (Service, SeedCode, LptNum, Pass1, Pass2 : word;var p1,p2,p3,p4 : word); external;{$F-}…经过{$L hasptpw.obj}宣告的后, 其它部分就可以直接呼叫原先位于 hasptpw.obj 中hsap这个了{$L+} 区域符号信息在{$L+}时, Delphi会额外加入些区域符号信息, 这使得我们可以应用Delphi IDE中 View/Call Stack, View/Watch在执行时检视变量内容和函式呼叫关系应用这个Compiler directive注意事项有:? {$D-}时, {$L+}不会有作用? 使用{$L+}, 只会加大.DCU档案大小, 对.EXE大小和执行速度并没有影响{$H+} 长串宣告Delphi 2.0的后, 串多了个更为好用长串, 不仅没有资料长度255限制,和C语言惯用Null-terminated 兼容性也大为提高使用{$H}时注意事项有:? {$H+}编译情形下, 以定义串变量都是长串, 请注意,串是否为长串是在串定义时决定, 例如:procedure TForm1.Button1Click(Sender: TObject);{$H-}vars: ;begin{$H+}s := ‘测试下长串’;Windows.MessageBox(0, pchar(s), ‘讯息’, 64);end;由于var前{$H-}缘故, 虽然在begin后我们立即设定为{$H+}, 但s仍然是个短串,所以, 自然不能像是长串样, 以pchar强制型别转换后当作Null-terminated串使用? 承上, 不管是{$H+}或{$H-}, 只要串是以长串方式定义, 即使begin..end;中改成{$H-}, 该串操作仍然具有长串特性因此, 由于VCL中串都是长串, 即使我们是{$H-}, 仍然可以拿它们当长串来使用? 不论{$H}状态如何, 以AnsiString定义定是长串; 以[n]或ShortString定义定是短串{$M 16386, 1048576} 内存配置大小要改变唯叠(Stack)内存配置大小时, 我们可以有以下两种选择:? 使用{$MINSTACKSIZE数字}, {$MAXSTACKSIZE数字}, 分别指定最小.最大Stack 大小.? 或者使用{$M min, max}, 同时指定最小和最大值使用这些Compiler directive时注意事项有:? 写在.DPR中才有效果? 堆栈最小数字必须介于1024至21474835647的间? 堆栈最大数字必须介于$MINSTACKSIZE至21474835647的间? 当内存不足而无法满足最小堆栈大小时, Windows会在激活这时提出报告? 当要求内存超过$MINSTACKSIZE大小时, 将举发EStackOverflow例外{$Z1} 最小列举大小这个Compiler directive将影响储存列举型态时最小所需数值如果宣告列举型态时, 数值不大于256, 而且也在系统预设{$Z1}时, 这个列举型态只占用个储存{$Z2}时, 以两个储存, {$Z4}时, 以 4个储存C语言通常以WORD或DWORD储存列举型态, 如果您需要和C、C沟通时,{$Z2}{$Z4}就很管用了{$Z+}, 和{$Z-}分别对应到{$Z1}和{$Z4}{$P+} 开放串参数在和宣告时, 其中串自变量, 在{$P+}时表示是Open ; {$P-}时,只是般串变量而已这个Compiler directive只在{$H-}时有作用{$O+} 最佳化开关建议您维持{$O+}系统默认值开启这个Compiler directive, Delphi会自动进行最佳化处理, 可以因此跑得快些, 您可以放心打开这个编译开关, Delphi不会进行不安全最佳化而使您执行时发生{$Q-} 满溢检查, {$R-} 范围检查{$Q}和{$R}是组搭配使用Compiler directive, 它们将检查数值或操作是否在安全边界中, {$Q}会检查整数运算(如+, -, Abs, Sqr, Pred,Succ等), 而{$R}则检查串和存取是否超出合理边界范围等问题使用这两个Compiler directives会这些检查动作而降低执行速度,通常我们会在除错时开启这两个编译开关{$U-} Pentium CPU浮点运算安全检查还记得早期Pentium CPU浮点运算不正确事吧? 这批CPU应该回收得差不多了,但如果您仍然不确定会不会意外遇到漏网的鱼或黑心牌经销商话, 请将这个 Compiler directives设为{$U+}根据Borland手册介绍说明, 如果CPU是没有暇疵, 设定{$U+}对于执行速度只有轻微 影响; 但如果是问题CPU, 浮点除法速度会因此慢上 3倍, 是否要打开这个开关,您心中应该已有取舍{$R文件名称} 资源档在您还没有开始学习Compiler directives的前, 这个指令就已经出现在您中了,每次开出个新form时, Delphi自动在Implement开头部分中加入{$R *.DFM},在Project/Source中看到.DPR中也有{$R *.RES}, 这些是什么意思呢? 意思是说,在编译连结时, 含入和项目主档名同名.RES, 以及和form unit档案同名.DFM等资源档 如果您需要在中使用额外资源(例如: 自订鼠标指针), 请注意不要自行以Resouse WorkShop或Image Editor等资源编辑器更改这些和Project或Form同名资源档,改变这些同名档案不仅无效, 可能还有不可预期因些,您应该在另外个资源档中存放这些资源, 并于{$R}中写明档案名称将其连结进来, 例如: {$R MyCursor.res}{$T-} @指针型态检查应用@操作数可以取得变量地址, 在{$T-}时, 以@取得是个无型别指针(Poer)反过来说, 在{$T+}时, 是有型别指针, 假定I是个eger变量, @I所得到即是相当于^Integer(Poer of Integer)指针{$WARNINGS _disibledevent=>beginVarConst := 5;ShowMessage(IntToStr(VarConst));end;const不是常数吗? 为什么可以改呢? 在先前Pascal版本中, 以const VarName: DataType = const value;定义具型态常数确是可以改, 假如您希望常数就是常数, 它不应该允许修改,请将这个Compiler directive设为{$J-}不论是{$J+}或{$J-}, 以const VarName = const value; 定义常数(没有加上型别宣告), 是个真正常数, 其它不可以改变其内容其实{$J+}时还有个妙用, 那就是宣告出类似C语言变量, 换句话说,产生了个和Application相同生命周期变量在这种情形下, 变量只在第次使用时才会建立, 或结束时, 该变量也不会消灭, 下次再呼叫到这个或时, 我们仍然可以参考到上次执行结束时值让我们试下这个例子:{$J+}procedure TForm1.Button1Click(Sender: TObject);consti: eger = 0;beginShowMessage(IntToStr(i));Inc(i);ShowMessage(IntToStr(i));end;第次执行时, 我们分别会看到「0」「1」, 再点次这个按钮时, 看到将是「1」「2」 2009-3-28 1:29:52 疯狂代码 /。

delphi常见编译和运行错误

delphi常见编译和运行错误

********************************编译错误信息********************************';' not allowed before 'ELSE'ElSE前不允许有“;”'' clause not allowed in OLE automation section在OLE自动区段不允许“”子句'' is not a type identifier不是类型标识符'' not previously declared as a PROPERTY前面没有说明PROPERTY'GOTO ' leads into or out of TRY statement GOTO 进入或超出TRY语句的范围clause expected, but found要求子句,但出现16-Bit fixup encountered in object file ''在对象文件遇到16位修复486/487 instructions not enabled不能用486/487指令Abstract methods must be virtual or dynamic抽象方法必须为虚拟的或动态的Array type required需要数组类型Assignment to FOR-Loop variable ''给FOR循环变量赋值Bad argument type in variable type array constructor在变量类型数组结构中不正确的参数类型Bad file format ''错误的文件格式Bad file format: 错误的文件格式Bad global symbol definition: '' in object file ''对象文件''中错误的全局符号定义''Bad unit format: 错误的单元格式BREAK or CONTINUE outside of loop BREAK或CONTINUE超出循环Cannot add or subtract relocatable symbols不能增加或减少可重置的符号Cannot assign to a read-only property不能指定只读属性Cannot BREAK, CONTINUE or EXIT out of a FINALLY clause超出FINALLY子句的范围,不能使用BREAK,CONTINUE或EXIT语句Cannot initialize local variables不能初始化局部变量Cannot initialize multiple variables不能初始化多个变量Cannot initialize thread local variables不能初始化线程局部变量Cannot override a static method不能覆盖静态方法Cannot read a write-only property不能读取只写属性Case label outside of range of case expression CASE标号超出了CASE表达式的范围Circular unit reference to 对单元循环引用Class already has a default property类已具有默认的属性Class does not have a default property类没有默认的属性Class or object types only allowed in type section在类型区段只允许有类或对象类型Class type required需要类类型Close error on 文件关闭错误Compile terminated by user用户中止编译Constant expected要求常量Constant expression expected要求常量表达式Constant expression violates subrange bounds常量表达式超出子界范围Constant object cannot be passed as var parameter常量对象不能作为变量参数传递Constant or type identifier expected要求常量或类型标识符Constants cannot be used as open array arguments常量不能用作打开数组参数Constructing instance of '' containing abstract methods构造的实体包含抽象的方法Could not compile used unit ''不能用单元编译Could not create output file 不能建立输出文件Could not load RLINK32.DLL不能加载RLINK32.DLLData type too large: exceeds 2 GB数据类型太大:超过2GBDeclaration of differs from previous declaration的说明与先前的说明不同Default property must be an array property默认的属性必须为数组属性Default values must be of ordinal, pointer or small set type默认的值必须为序数、指针或小集类型Destination cannot be assigned to目标不能指定Destination is inaccessible目标不能存取Dispid '' already used by ''DISPID标识号已被使用Dispid clause only allowed in OLE automation section DISPID子句只能在OLE自动区段中使用Division by zero除数为零Duplicate case label CASE标号重复Duplicate tag value重复的标志值Dynamic method or message handler not allowed here这里不允许有动态方法或信息处理程序Dynamic methods and message handlers not allowed in OLE automation section在OLE自动区段不允许有动态方法或消息处理程序Element 0 inaccessible - use 'Length' or 'SetLength'元素0不能存取-使用LENGTH或SETLENGTHError in numeric constant数值常量错误EXCEPT or FINALLY expected要求EXCEPT或FINALLYEXPORTS allowed only at global scope EXPORTS 只允许在全局范围使用Expression has no value表达式没有值Expression too complicated表达式太复杂Field definition not allowed in OLE automation section在OLE自动区段中不允许域定义Field definition not allowed after methods or properties在方法或属性后不允许域定义Field or method identifier expected要求域或方法标识符File not found: 文件没有找到File type not allowed here这儿不允许文件类型For loop control variable must be simple local variable FOR循环控制变量必须为简单局部变量For loop control variable must have ordinal type FOR循环控制变量必须为序数类型FOR or WHILE loop executes zero times - deleted FOR或WHILE循环执行零次-删除FOR-Loop variable '' cannot be passed as var parameter FOR循环变量不能作为参数传递FOR-Loop variable '' may be undefined after loop在循环后的FOR循环变量是不确定的Function needs result type函数需要结果类型Identifier redeclared: ''标识符重复说明Illegal character in input file: '' ($)在输入文件中的非法字符'' Illegal message method index非法的消息方法指针Illegal reference to symbol '' in object file ''在对象文件中对符号的非法引用Illegal type in OLE automation section: ''在OLE自动区段中的非法类型Illegal type in Read/Readln statement在Read/Readln 语句中的非法类型Illegal type in Write/Writeln statement在Write/Writeln 语句中的非法类型Inaccessible value不可存取的值Incompatible types: '' and ''不兼容的类型和Incompatible types: 不兼容的类型Inline assembler stack overflow内联汇编溢出Inline assembler syntax error内联汇编语法错误Instance variable '' inaccessible here实体变量在这里不能存取Integer constant or variable name expected要求整形常量或变量名Integer constant too large整型常量太大Internal error: 内部错误Invalid combination of opcode and operands操作码与操作对象的无效组合Invalid compiler directive: ''无效的编译指令Invalid function result type无效的函数值类型Invalid message parameter list无效的消息参数列表Invalid register combination无效的寄存器组合Invalid typecast无效的TYPECASELabel '' is not declared in current procedure在当前的过程中没有说明标号Label already defined: ''标号已经定义Label declaration not allowed in inte**ce part在界面部分不允许标号说明Label declared and referenced, but not set: ''标号被说明及引用,但不能设置Label expected要求标号Left side cannot be assigned to左边不能赋值Line too long (more than 255 characters)行太长(超出255个字符)Local class or object types not allowed不允许局部的类或对象类型Local procedure/function '' assigned to procedure variable局部过程/函数赋给过程变量LOOP/JCXZ distance out of range LOOP/JCXZ距离超出范围Low bound exceeds high bound下界超过上界Memory reference expected要求内存引用Method '' hides virtual method of base type ''方法隐藏了基类型为的虚拟方法Method '' not found in base class在基类中没有找到方法Method identifier expected要求方法标识符Missing ENDIF directive缺少ENDIF指令Missing operator or semicolon缺少操作符或分号Missing or invalid conditional symbol in '$' directive在$指令中缺少或无效的条件符号Missing parameter type缺少参数类型Necessary library helper function was eliminated by linker必要的库帮助函数被连接程序删除No definition for abstract method '' allowed抽象方法没有定义Not enough actual parameters没有足够的实际参数Number of elements differs from declaration元素数与说明不同Numeric overflow数值溢出Object or class type required需要对象或类类型Object type required需要对象类型Only register calling convention allowed in OLE automation section在OLE自动区段中只允许寄存器调用约定Operand size mismatch运算对象大小匹配Operator not applicable to this operand type运算符不使用于这一运算对象类型Order of fields in record constant differs from declaration在记录常量中的域次序与说明不同Ordinal type required需要序数类型Out of memory内存溢出Overflow in conversion or arithmetic operation转换或算术操作溢出Overriding automated virtual method '' cannot specify a dispid覆盖的自动虚拟方法不能指定DISPIDPACKED not allowed here这里不允许PACKEDPointer type required需要指针类型Procedure cannot have a result type过程不能有结果类型Procedure DISPOSE needs destructor过程DISPOSE需要destructorProcedure FAIL only allowed in constructor过程FAIL只允许在constructor方法中Procedure NEW needs constructor过程NEW 需要constructor方法PROCEDURE or FUNCTION expected要求PROCEDURE或FUNCTIONProcedure or function name expected要求过程或函数名Program or unit '' recursively uses itself程序或单元递归Property '' does not exist in base class在基类中属性不存在Published property '' cannot be of type Published属性不能具有类型Published Real48 property '' must be Single, Double or Extended Published REAL属性必须为Single, Double或ExtendedRe-raising an exception only allowed in exception handler在意外处理中只允许重新引起意外处理Read error on 文件读出错Record, object or class type required需要记录,对象或类类型Redeclaration of '' hides a member in the base class的重新说明隐藏了基类中Redeclaration of property not allowed in OLE automation section在OLE自动区段中不允许属性重复说明Return value of function '' might be undefined函数的返回值可能没有定义Seek error on 在中搜索错误Segment/Offset pairs not supported in Borland 32-bit Pascal在Borland 32位的PASCAL中不支持Segment/Offset对Sets may have at most 256 elements集至少有256个元素Size of published set '' is >32 bits published集的大小大于32字节Slice standard function only allowed as open array argument Slice标准函数只允许作为打开数组参数Statement expected, but expression of type '' found要求语句,但出现类型的表达式Statements not allowed in inte**ce part在界面中不允许的语句String constant too long字符串常量太长String constant truncated to fit STRING[]字符串常量截取到适合STRING[]Strings may have at most 255 elements字符串至少255个元素Structure field identifier expected要求结构域标识符Syntax error in real number实数语法错误System unit out of date or corrupted: missing ''系统单元超出日期或损坏:缺少Text after final 'END.编译器忽略END.后的文本This form of method call only allowed for class methods该方法的窗体只允许类方法This form of method call only allowed in methods of derived types该方法的窗体只允许在导出类型的方法中This type cannot be initialized这一类型不能初始化Thread local variables cannot be ABSOLUTE线程局部变量不能是ABSOLUTEThread local variables cannot be local to a function or procedure线程局部变量对函数不能是局部的Too many actual parameters太多的实际参数Too many conditional symbols太多的条Type '' has no type info类型没有类型信息Type '' is not yet completely defined类型至今没有定义Type '' must be a class to have a PUBLISHED section类型必须是在PUBLISHED区段中的类Type '' must be a class to have OLE automation类型必须是具有OLE 自动的类Type '' needs finalization - not allowed in file type类型需要初始化-不允许在文件类型中Type '' needs finalization - not allowed in variant record类型需要初始化-不允许在变体记录Type expected要求TYPEType not allowed in OLE Automation call在OLE自动调用中不允许的类型Type of expression must be BOOLEAN表达式的类型必须为BOOLEAN型Type of expression must be INTEGER表达式的类型必须为INTEGER型TYPEINFO standard function expects a type identifier TYPEINFO标准函数要求类型标识符TYPEOF can only be applied to object types with a VMT TYPEOF只能用于具有VMT的对象类型Types of actual and formal var parameters must be identical形参与实参必须一致Undeclared identifier: ''未说明的标识符Unexpected end of file in comment started on line 以行开始的注释中出现不应有的文件结束Unit was compiled with a different version of 单元与不同版本的编译Unit name mismatch: ''单元名不匹配Unknown directive: ''未知的指令Unnamed arguments must precede named arguments in OLE Automation call在OLE自动调用中未命名的参数必须在命名的参数前Unsatisfied forward or external declaration: ''不满足的向前或外部说明Unterminated string未结束的字符串V alue assigned to '' never used赋给的值从未使用过V ariable '' inaccessible here due to optimization由于优化,变量名在这里不能存取V ariable '' is declared but never used in ''变量名已说明,但不曾使用V ariable '' might not have been initialized变量名可能没有初始化V ariable required需要变量Virtual constructors are not allowed不允许虚拟的constructors方法Write error on 文件写错误Wrong or corrupted version of RLINK32.DLL RLINK32.DLL版本错误或不能用********************************运行错误信息** 运行时出现的错误信息形式为: ** Run-time error nnn at xxxx** 其中nnn 是运行时的错误编号** xxxx 是运行时的错误地址********************************运行时的错误分为以下三类:* I/O错误:错误编号为100-149编号说明---------------------------------------------------------100磁盘读错误,若要对超过格式文件尾进行读取时101磁盘写错误,若磁盘满时,由CloseFile,Write,Writeln或Flush报告102没有指定文件,若文件变量没有由Assign或AssignFile赋值,由Reset,Rewrite,Append,Rename和Erase报告103文件没有打开,若文件未打开,由CloseFile,Read,Write,Seek,Eof,FilePos,FileSize,Flush,BlockRead或BlockWrite报告104输入文件未打开,由Read,Readln,Eof,Eoln,SeekEof或SeekEoln报告有关输入的文本文件未打开105输出文件未打开,由Write和Writeln报告有关文本文件没有用Console应用程序生成106无效的数据格式,由Read或Readln报告从文本文件读取的数据格式不正确* 致命错误:错误编号为200-255编号说明---------------------------------------------------------200被零除201范围检查错误202栈上溢203栈上溢错误204无效的指针操作205浮点上溢206浮点下溢207无效的浮点操作215算术上溢错误216存取非法217控制-C218授权指令219无效的TYPECAST220无效的变体TYPECAST221无效的变体操作222没有变体方法调用DISPA TCHER223不能建立变体数组224变体不包含数组225变体数组边界错误226TLS初始化错误* 操作系统错误编号说明---------------------------------------------------------1899L不能生成端点映射数据库1752L不能执行操作1751L入口点非法1753L端点映射中没有更多可用的端点5L存取非法1331L帐号当前不能用,因此不能登录1793L用户帐号过期1327L用户名是有效的,但一些限制不能验明用户57L网络适配器硬件错误1379L指定的别名已存在1344L分配用于更新的内存块不足85L本地设备名已在使用183L试图建立已存在的文件1074L系统当前正以最新最好的配置运行7L存储控制块被破坏534L运算结果超出32位174L文件系统不支持锁定类型的原子变化199L操作系统不能运行这一程序160L传递给DosExecPgm的参数串不正确22L设备不能识别的命令1361L安全描述符不在要求的格式66L网络资源类型不正确1200L指定的设备名无效119L系统不支持请求的命令10L环境不正确193L%1不是有效的基于Windows的应用程序11L企图装载不正确格式的程序1346L指定的模拟级无效或没有提供要求的模拟级1340L试图建立继承的ACL或没有继承的ACE 24L程序指定的命令长度不正确1365L登录段与要求的操作状态不一致67L网络名找不到58L指定的服务器不能执行请求的命令53L网络路径没有找到161L指定的路径名无效230L管道状态无效1206L网络连接协议被损坏1204L指定的网络提供者名无效60L远程适配器不兼容159L线程ID地址不正确1349L符号对象类型不当20L系统不能找到指定的设备2202L指定的用户名无效1348L请求的确定信息类是无效的1009L配置记录数据库被破坏1010L配置记录密钥无效1102L遇到磁带头或分区1076L当前引导已接受为最新的控制设置109L管道结束111L文件名太长1111L I/O总线重新设置170L请求的资源在使用142L此时系统不能执行JOIN或SUBST120L输入的API只能在Windows/NT模式下工作1003L由于一些原因不能完成的功能173L锁定请求对提供撤消区未解决266L不能使用1407L不能找到Windows类1368L表示要试图通过命名管道的模拟还没有读取82L不能生成目录或文件1205L不能打开网络连接协议1351L没有联系的域控制器或在域内对象被保护,因此不能存取必要信息1310L委托组不能禁止1347L试图打开匿名的符号,匿名级的符号不能打开1011L配置记录密钥不能打开1012L配置记录密钥不能读取1013L配置记录密钥不能写1021L试图在易变的父关键字下建立稳定的子关键字129L应用程序%1不能在Windows模式下运行1436L子窗口不能有菜单1059L指定子循环服务从属1410L类已存在1411L类不存在1412L类仍在打开的窗口中1418L线程没有打开的剪切板1201L设备当前没有连接,但要记住连接1421L没有找到控制ID1121L由于超时已到,一系列的I/O操作完成23L数据错误16L目录不能删除1065L指定的数据库不存在1425L传递给ReleaseDC的无效HDC1051L终止控制已送到其他独立运行服务的服务中1435L不能破坏其他线程产生的对象55L指定的网络资源不再有效1202L试图记住先前记住的设备2404L设备由激活的进程在使用,不能断开连接1107L当装载磁带时,找不到磁带的分区信息145L目录非空144L目录不是根目录的子目录130L试图使用文件句柄来打开磁盘操作267L目录名无效157L段已丢失,不能锁定107L由于没有插入交换磁盘,程序终止1393L磁盘结构损坏,不能在读取112L磁盘上没有足够的空间1127L即使重试,存取硬盘也失败1126L在存取硬盘时,即使重试,存取校准操作也失败1128L即使磁盘控制器重新设置,存取硬盘也失败1114L DLL初始化例程失败1356L指定的域已存在1357L在该版本中试图超出每个服务器域的限制1810L指定域的名字或安全ID与该域的受托信息不一致108L磁盘在使用或被其他进程锁定1221L工作族或域名已被网络上的其他计算机使用52L网络上存在重名1078L名字已在作服务器名或服务显示名使用196L操作系统不能运行这一应用程序994L对EA的存取非法276L在安装文件系统上的EA文件被损坏255L EA不一致277L在安装文件系统的EA文件上的EA表用完275L EA不适合在缓冲区中282L安装文件系统不支持扩展属性1100L在操作中出现磁带尾部标志203L系统不能找到输入的环境选项1129L遇到磁带的物理尾部1501L没有打开的日志文件事件,因此事件登录服务没有启动1503L在读取之间事件日志文件已改变1500L Eventlog登录文件之一破坏1064L在处理控制请求时出现意外101L专门信号被其他进程所拥有192L操作系统不能运行%11208L出现扩展错误83L INT24失败1063L服务进程不能连接到服务控制器1392L文件或目录被损坏,不能在读取80L文件存在1006L文件卷已变化,因此打开的文件不再有效2L系统不能找到指定的文件1101L磁带存取达到文件标志206L文件名或后缀太长1125L软盘控制器返回与登记不一致的结果1122L在软盘上没有找到ID地址标志1123L软盘扇区ID域与软盘控制器道地址不匹配1124L软盘控制器报告出现不能由软驱识别的错误1007L请求的操作在全屏幕模式不能执行31L连接到系统上的设备不正常1360L通配存取类型包含在存取屏蔽中1429L该异常分支只能为全局设置1318L指定的组已存在39L磁盘满38L到达文件末1428L没有模块处理,不能设置非局部的异常处理1431L异常分支没有安装1409L热键已登记1419L热键没有登记1441L所有的DeferWindowsPosHWND必须具有相同的父1324L在更新口令时,该返回状态表示新口令中包含不允许的值202L操作系统不能运行%1122L传递给系统调用的数据区太小1358L由于灾难性的介质错误或磁盘数据结构破坏引起请求的操作不能完成1383L LSA数据库内部不一致1359L SAM遇到内部数据库不一致的错误,可防止SAM的进一步操作1800L指定的优先级无效1448L滚动条范围大于0x7FFF1338L安全描述符结构无效198L操作系统不能运行%1180L系统检测到不正确的段号1799L指定的分隔符文件无效1352L SAM服务器状态错误,不能完成期望的操作1057L帐号名无效或不存在1052L对该服务请求的控制无效1071L指定的服务数据锁定无效1213L指定的服务名格式无效1215L指定的共享名格式不正确1449L SHOWWINDOWS命令无效1337L SID结构无效209L公布的信号不正确1439L参数无效189L操作系统不能运行%1188L操作系统不能运行%11335L子权限值无效114L目标内部文件标识符不正确1444L线程ID无效1784L提供的用户缓冲区对请求操作失效118L写后验证开关参数值不正确1400L窗口处理无效1329L用户帐号限制,不能从源工作站登录1117L由于I/O设备错误,请求不能完成996L重叠的IO时间不在发信号状态997L重叠的IO操作在处理中197L操作系统当前不能配置来运行应用程序1119L不能打开与其它设备共享IRQ的设备,至少有一使用该IRQ的其他设备已打开147L没有足够的可用资源来处理这一命令133L由于驱动器已包含连接,JOIN或SUBST命令不能使用134L试图在已连接的驱动器上使用JOIN或SUBST命令146L指定的路径正在用替换149L试图替代先前已替代的驱动器目录135L试图在已替代的驱动器上使用JOIN或SUBST命令194L操作系统不能运行%1138L系统试图替代已替代的目录140L系统试图替代已替代的目录1430L日常异常处理已安装1018L在有删除标志的登记键上非法操作1020L试图在已有子键或值的登记键建立符号连接154L输入的卷标超过11个字符的限制,前11个字符写在磁盘上,其余字符自动删除1322L请求的操作被禁止或删除最新的其余管理员帐号1434L该列表框不支持制表符1416L列表符ID没有找到1390L试图修改用户口令,但没有提供要求的LM口令1303L联接局部RPC,要求用户话路密钥167L试图锁定文件失败的区域33L由于其他进程已锁定部分文件,该文件不能被进程存取212L端锁定,因此不能重新分配1502L事件登录文件已满1326L由于用户名或验证信息不正确,试图登录无效1380L请求登录的类型(如网络,服务等)没有被目标系统授权1366L登录话路ID已在使用1363L试图启动新的话路管理程序或用已在使用的LSA登录话路1385L请求登录的类型(如网络,服务等)没有授权1334L没有更多可分配的LUID164L在系统中不能生成更多的线程1110L驱动器中的介质已改变1378L指定的帐号名不是别名的成员1320L指定的用户帐号已在指定的组帐号中或由于组中有成员,不能删除1377L指定的帐号名不是别名的成员1321L指定的用户帐号不是指定组帐号的成员1374L由于组是基本组,因此成员不能从该组中删除208L取决文件名符号*或?输入不正确或指定的全局文件符号更多126L不能找到指定的模块234L需要更多的数据1120L一系列的I/O操作被其他写到串口的操作完成317L系统不能找到消息号为0x%1的消息131L试图在超出文件头的位置移动文件指针215L不能嵌套调用LoadModule1792L试图登录,但网络登录服务没有启动88L网络写失败64L指定的网络名不再有效65L网络存取非法54L网络在忙6118L该工作组的服务器列表当前不可用232L管道在进程中关闭1104L在磁带存取中,到达数据标志尾部1309L试图由当前不在模拟客户的线程上操作模拟符号1391L ACL不包含可继承的组件1019L系统不能分配记录文件要求的空间1807L使用的帐号在内域受托帐号中,使用正常的帐号或远程用户帐号来存取该服务器1809L使用的帐号在服务器受托帐号中,使用正常的帐号或远程用户帐号来存取该服务器1311L当前没有可用的登录服务器来服务登录请求1808L使用的帐号在工作站受托帐号中,使用正常的帐号或远程用户帐号来存取该服务器1112L由于驱动器中没有介质,磁带查询失败18L没有更多的文件259L没有更多的可用数据113L没有更多的可用内部文件标识符1203L没有网络提供者接收给定的路径2138L没有网络或网络未启动89L此时系统不能启动另一进程1302L对该帐号没有指定限额1447L窗口不能有滚动条1350L试图对没有安全性的对象操作1116L由于没有关机在处理中,试图放弃关机失败205L在命令子树中没有进程有信号句柄62L在服务器上存储等待打印文件的空间不足1376L指定的别名不存在1355L指定的域不存在1319L指定的组不存在1312L指定的登录话路不存在,可能已终止1387L不存在的新成员不能添加到别名中1364L指定的验证包未知1313L指定的特权不存在1317L指定的用户不存在1437L窗口不能具有系统菜单1008L试图引用不存在的符号1786L工作站没有受托秘密1787L域控制器对该工作站没有帐号1113L对目标多字节代码页存在的Unicode字符没有映射1394L对指定的登录话路没有用户话路密钥125L磁盘没有卷标1417L没有找到通配符998L对内存位置的无效存取1445L用非MDI子窗口调用DefMDIChildProc1332L映射的信息没有转变1300L不是所有权限赋给调用者1442L窗口不是子窗口2250L网络连接不存在1207L不能枚举非容器26L指定的磁盘不能存取8L没有足够的空间处理该命令1130L没有足够的空间处理该命令服务器136L系统试图删除没有连接的驱动器158L段已锁定1362L请求的动作只受登录进程的限制,调用进程没有登记为登录进程288L试图释放不被调用者拥有的互斥法21L驱动器没有准备好1017L系统试图装载或恢复文件到登记中,但指定的文件格式不正确17L系统不能将文件移动到不同的驱动器上137L系统试图删除没有替代的驱动器50L不支持网络请求1022L改变请求正在完成,信息没有返回在调用者的缓冲区.调用者现在需要模拟文件,以找到所做的修改1386L没有提供必要的NT交叉保密口令而试图以安全帐号管理员改变用户口令1304L WindowsNT的口令太复杂,无法将其转换为Windows的网络口令(该口令返回NULL字符串)110L系统不能打开指定的设备或文件2401L有打开文件或请求在连接期995L由于线程退出或应用程序请求,I/O操作放弃28L打印机没有纸84L处理该请求没有足够的空间14L处理该操作没有足够的空间1105L磁带没有分区1330L用户帐号的口令已到期1325L在更新口令,该状态表示违反一些口令更新规则148L指定的路径现在不能用3L系统不能找到指定的路径231L所有的管道实体在忙535L在管道的另一端有进程536L等待进程打开管道的另一端233L在管道的另一端没有进程1446L下拉式菜单已激活1131L已检测到潜在的僵局条件63L要打印的等待文件被删除1802L打印机已存在1795L指定的打印驱动程序已安装61L打印队列已满1415L使用局部的DIALOG窗口字1314L请求的权限客户机没有127L指定的过程没有找到1067L进程突然终止30L系统不能从指定的驱动器读取72L指定的打印机或磁盘驱动器已暂停1794L重定向器在使用,不能卸载1015L登记文件的文件结构或文件的内存印象系统损坏或文件不能恢复1016L登记初始化I/O操作有不可恢复的错误,登记不能完成读,写等操作1014L包含系统登记数据的文件之一已恢复成功201L操作系统不能运行%151L远程计算机不可用1220L试图建立LAN管理服务器话路,但已建立了很多71L网络请求不接受1816L处理该命令没有足够的定额1812L指定的图象文件不包含资源部分1815L指定的资源语言ID在图象文件中找不到1814L指定的资源名在图象文件中找不到1813L指定的资源类型在图象文件中找不到1306L两个版本级不兼容207L2环堆栈在使用200L代码段不能大于等于64KB1370L在登记事务委托中出现错误1369L登记子树的事务状态与请求的操作不兼容143L系统不能替代相同的驱动器或目录1440L屏幕已锁定1382L秘密的长度超出允许的最大长度27L驱动器没有找到请求的扇区25L驱动器不能找到磁盘上指定的区域和道132L文件指针不能设置在指定的设备或文件上102L信号设置不能关闭187L指定的系统信号名没有找到105L该信号的先前物主关系已终止121L信号超时期已到106L在驱动器1中插入磁盘1118L串行设备没有初始化,串行设备没有安装1341L GUID分配服务器此时禁止1811L服务器在使用中,不能卸载1342L此时允许GUID分配服务器1056L服务实体已在运行1061L服务在此时不能接受控制消息1055L服务数据库锁定1075L从属服务不存在或已做删除标志1068L从属服务或组启动失败1058L指定服务禁止,不能启动1060L指定作为安装的服务不存在1073L指定的服务已存在1069L由于登录失败,服务不能启动1072L指定的服务已做删除标志1077L引导后没有启动的服务已启动1054L不能产生该服务的线程1062L服务没有启动1053L服务对启动没有响应或及时地控制请求1066L服务已返回一服务指定错误代码1070L在启动后,服务挂在启动等待状态1219L提供的证书与已有证书集冲突1433L LB_SETCOUNT发送到非缓慢的列表框1103L磁带存取达到设置标志36L打开的共享文件太多70L远程服务暂停或在启动的过程中32L由于文件被其他进程使用,该进程则不能存取1115L系统关闭在处理中。

使用Delphi对象(声明、实例化、构造、释放)

使用Delphi对象(声明、实例化、构造、释放)

使⽤Delphi对象(声明、实例化、构造、释放)⼀、声明和实例化 在使⽤⼀个对象之前,⽤class关键字声明⼀个对象。

可以在⼀个程序或单元的type部分声明⼀个对象类型:typeTFooObject = class; 除了声明⼀个对象类型,通常还需要⼀个对象的变量,即实例。

实例定义在var部分varFooObject; TFooObject; 在Delphi中通过调⽤它的⼀个构造器来建⽴⼀个对象的实例,构造器主要是⽤来为对象创建实例并为对象中的域分配内存进⾏初始化使得对象处于可使⽤的状态。

Delphi的对象⾄少有⼀个构造器称为create(),但是⼀个对象可以有多个构造器。

根据不同的对象类型,Create()可以有不同的参数。

不像在C++中,在Delphi中构造器不能⾃动调⽤,程序员必须⾃⼰调⽤构造器,调⽤构造器的语法如下FooObject:= TFooObject.Create; 注意这⾥调⽤构造器的语法有⼀点特殊,是通过类型来引⽤⼀个对象的Create()⽅法,⽽不是像其他⽅法那样通过实例来引⽤。

这看上去有点奇怪,但是很有意义。

变量FooObject在调⽤时还没有被定义,⽽TFooObject已经静态地存在于内存之中,静态调⽤它的Create()⽅法是合法的。

通过调⽤构造器来创建对象的实例,这就是所谓的实例化 注意:当⼀个对象实例⽤构造器创建的时候,编译器将对对象的每⼀个域经⾏初始化,你可以放⼼地认为所有数字被赋值为0,所有指针赋值为NIL,所有字符串为空⼆、析构 当⽤完对象,应该调⽤这个实例的Free()⽅法来释放它。

Free()⾸选进⾏检查保证这个对象实例不为NIL,然后调⽤对象的析构⽅法Destroy()。

⾃然,析构进⾏与构造相反的⼯作,它释放所有分配的空间,并执⾏⼀些其他操作以保证对象能够适当地移除内存。

语法FooObject.free; 不像调⽤Create(),这⾥是调⽤对象实例的Free()⽅法,记住不要直接调⽤Destroy(),⽽调⽤更安全的Free()⽅法,因为Free()⾸选进⾏检查保证这个对象实例不为NIL,然后调⽤对象的析构⽅法Destroy()。

Delphi工具反编译Delphi

Delphi工具反编译Delphi

Delphi工具反编译Delphi第一节关于反向工程(About Reverse Engineering)反编译?反向?解密?(Decompilation? Reverse? Cracking?)简单的说,反编译是编译过程的反转:把一个可执行文件翻译为更高级语言。

假如你丢失了你的Delphi工程的源程序而只有可执行文件:如果源程序已不可得则反向工程(反编译)是有用的。

耶,“源程序不可得”,这是否意味着我们可以反编译别的程序员开发的Delphi工程呢?嗯,对也不对......真正的反编译可能吗?(Is true decompilation possible?)不,当然不行。

完全自动的反编译是不可能的—没有一个反编译器可以正确的重生出原始代码。

当Delphi工程被编译和连接从而产生一个独立的可执行文件,程序中使用的大部分的名称都被转换为地址。

名称的丢失意味着反编译器必须为所有的常量、变量、函数和过程创建唯一的名称。

即使在某种程度上反编译是成功的,产生的“源代码”仍缺少了原始含义的变量和函数名。

显而易见,原始编程语言的语法在可执行文件中已不存在。

所以,让反编译器对可执行文件的连续的机器语言指令进行翻译并判断出原始语言指令是非常困难的。

为什么要使用并且什么时候使用呢(Why and when to use.)反向工程因为以下几个原因而使用:丢失源码的恢复;把应用程序移入新的硬件平台;判断程序中是否存在病毒或恶意代码;当程序拥有者不能更正错误时的程序错误的更正;其它开发人员的程序源代码的恢复(如:测定一个算法)这合法吗?(Is this legal?)反向工程不是解密,尽管很难在两者之间划一个明晰的界限。

计算机程序被版权和商标法保护。

不同的国家对版权拥有者的权利有着不同的解释。

最共同的解释是,下列情况下的反编译是可以的:为了更好的解释的目的,而接口说明已不可得;为了错位更正的目的,而版权拥有者不能进行更正;为了判断程序的部分内容是否被保护。

Delphi-条件判断那些事

Delphi-条件判断那些事

Delphi-条件判断那些事技术交流,DH讲解.之前照着天书夜读,⽤Delphi来弄了下循环体,现在就来弄⼀下条件判断吧.⾸先肯定是我们经常看见的IF语句咯.VarI: Integer;BeginI:= 99;If (I> 0)And (I< 0) ThenWriteln('I>0')ElseIf (I> 10)And (I< 100) ThenWriteln('I>10 and I<100')ElseWriteln('I>100');End.反汇编出来会是什么样⼦的呢?Project5.dpr.12: I:= 99;004AC44C B863000000 mov eax,$00000063Project5.dpr.13: If (I> 0)And (I< 0) Then004AC451 85C0 test eax,eax004AC453 7E1F jle $004ac474004AC455 85C0 test eax,eax004AC457 7D1B jnl $004ac474Project5.dpr.14: Writeln('I>0')004AC459 A1DC314B00 mov eax,[$004b31dc]004AC45E BAC4C44A00 mov edx,$004ac4c4004AC463 E874BAF5FF call @Write0UString004AC468 E8BF89F5FF call @WriteLn004AC46D E83E7FF5FF call @_IOTest004AC472 EB3E jmp $004ac4b2Project5.dpr.16: If (I> 10)And (I< 100) Then004AC474 83F80A cmp eax,$0a004AC477 7E20 jle $004ac499004AC479 83F864 cmp eax,$64004AC47C 7D1B jnl $004ac499Project5.dpr.17: Writeln('I>10 and I<100')004AC47E A1DC314B00 mov eax,[$004b31dc]004AC483 BAD8C44A00 mov edx,$004ac4d8004AC488 E84FBAF5FF call @Write0UString004AC48D E89A89F5FF call @WriteLn004AC492 E8197FF5FF call @_IOTest004AC497 EB19 jmp $004ac4b2Project5.dpr.19: Writeln('I>100');004AC499 A1DC314B00 mov eax,[$004b31dc]004AC49E BA04C54A00 mov edx,$004ac504004AC4A3 E834BAF5FF call @Write0UString004AC4A8 E87F89F5FF call @WriteLn004AC4AD E8FE7EF5FF call @_IOTest我们这⾥就容易得出来Delphi⾥⾯IF语句的结构了.判断1不满⾜就跳-------------------------|满⾜条件代码 |[⽆条件Jmp到所有判断外] |[判断2] <------| ...............................................就是这样的在IF的反汇编上⾯和书中的VC反汇编出来的代码差不多.接下来就是看switch语句(Delphi⾥⾯的Case):VarI: Integer;BeginI:= 9;Case I Of0:Writeln('0');1:Writeln('1');2:Writeln('2');3:Writeln('3');4:Writeln('4');5:Writeln('5');6:Writeln('6');7:Writeln('7');ElseWriteln('0');End;End.反汇编⼀下:Project5.dpr.12: I:= 9;004AC44C B809000000 mov eax,$00000009Project5.dpr.13: Case I Of004AC451 83F807 cmp eax,$07004AC454 0F8703010000 jnbe $004ac55d004AC45A FF248561C44A00 jmp dword ptr [eax*4+$4ac461] 004AC461 81C44A009EC4 add esp,$c49e004a004AC467 4A dec edx004AC468 00BBC44A00D8 add [ebx-$27ffb53c],bh004AC46E C44A00 les ecx,[edx+$00]004AC471 F5 cmc004AC472 C44A00 les ecx,[edx+$00]004AC475 0FC54A0029 pextrw ecx,qword ptr [edx+$00],$29 004AC47A C54A00 lds ecx,[edx+$00]004AC47D 43 inc ebx004AC47E C54A00 lds ecx,[edx+$00]Project5.dpr.15: Writeln('0');004AC481 A1DC314B00 mov eax,[$004b31dc]004AC486 66BA3000 mov dx,$0030004AC48A E8DDADF5FF call @Write0WChar004AC48F E89889F5FF call @WriteLn004AC494 E8177FF5FF call @_IOTest004AC499 E9D7000000 jmp $004ac575Project5.dpr.17: Writeln('1');004AC49E A1DC314B00 mov eax,[$004b31dc]004AC4A3 66BA3100 mov dx,$0031004AC4A7 E8C0ADF5FF call @Write0WChar004AC4AC E87B89F5FF call @WriteLn004AC4B1 E8FA7EF5FF call @_IOTest004AC4B6 E9BA000000 jmp $004ac575Project5.dpr.19: Writeln('2');004AC4BB A1DC314B00 mov eax,[$004b31dc]004AC4C0 66BA3200 mov dx,$0032004AC4C4 E8A3ADF5FF call @Write0WChar004AC4C9 E85E89F5FF call @WriteLn004AC4CE E8DD7EF5FF call @_IOTest004AC4D3 E99D000000 jmp $004ac575Project5.dpr.21: Writeln('3');004AC4D8 A1DC314B00 mov eax,[$004b31dc]004AC4DD 66BA3300 mov dx,$0033004AC4E1 E886ADF5FF call @Write0WChar004AC4E6 E84189F5FF call @WriteLn004AC4EB E8C07EF5FF call @_IOTest004AC4F0 E980000000 jmp $004ac575Project5.dpr.23: Writeln('4');004AC4F5 A1DC314B00 mov eax,[$004b31dc]004AC4FA 66BA3400 mov dx,$0034004AC4FE E869ADF5FF call @Write0WChar004AC503 E82489F5FF call @WriteLn004AC508 E8A37EF5FF call @_IOTest004AC50D EB66 jmp $004ac575Project5.dpr.25: Writeln('5');004AC50F A1DC314B00 mov eax,[$004b31dc]004AC514 66BA3500 mov dx,$0035004AC518 E84FADF5FF call @Write0WChar004AC51D E80A89F5FF call @WriteLn004AC522 E8897EF5FF call @_IOTest004AC527 EB4C jmp $004ac575Project5.dpr.27: Writeln('6');004AC529 A1DC314B00 mov eax,[$004b31dc]004AC52E 66BA3600 mov dx,$0036004AC532 E835ADF5FF call @Write0WChar004AC537 E8F088F5FF call @WriteLn004AC53C E86F7EF5FF call @_IOTest004AC541 EB32 jmp $004ac575Project5.dpr.29: Writeln('7');004AC543 A1DC314B00 mov eax,[$004b31dc]004AC548 66BA3700 mov dx,$0037004AC54C E81BADF5FF call @Write0WChar004AC551 E8D688F5FF call @WriteLn004AC556 E8557EF5FF call @_IOTest004AC55B EB18 jmp $004ac575Project5.dpr.31: Writeln('0');004AC55D A1DC314B00 mov eax,[$004b31dc]004AC562 66BA3000 mov dx,$0030004AC566 E801ADF5FF call @Write0WChar004AC56B E8BC88F5FF call @WriteLn004AC570 E83B7EF5FF call @_IOTest在这⾥我们看到了⼀个Delphi的优化,它⾸先把I和7⽐,如果⼤于就直接跳到else语句那⾥.如果⼩于等于,我们看到是⽆条件Jmp到⼀个I为等间距偏移的地⽅,也就是每个writeln语句是等⼤⼩的.要是我们改成不是01234567呢?⼤家⾃⼰试⼀下,不是等距case代码还是没有变.⽽VC⾥⾯会怎么样?cmp->je->cmp->je->cmp->je就是这样不停的对⽐,如果相等就跳.这样符合我们思维⼀些.好的,这书这⼀节会有⼀个课后题.哈哈,我也去做⼀下.下⼀次讲下结构体反汇编的东西吧.。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

DELPHI定义的条件编译的全部说明经常看到一些程序里面用到如:{$ifdef win16},{$ifdef win32}之类的信息,可是这些好像并没有定义,不知道在哪里可以找到这些条件编译的定义或者是说明具体讲述win16代表什么,WIN32代表什么,VER140。

代表什么的?{$IFDEF WIN32} -- 这可不是批注喔!对于Delphi来说﹐左右大括号之间的内容是批注﹐然而「{$」(左括号后紧接着货币符号)对于Compiler(编译器)而言并不是批注﹐而是写给Compiler看的特别指示。

应用时机与场合Delphi中有许许多多的Compiler Directives(编译器指令)﹐这些编译指令对于我们的程序发展有何影响呢? 它们又能帮我们什么忙呢?Compiler Directive 对程序开发的影响与助益, 可以从以下几个方向来讨论:?协助除错? 版本分类?程序的重用与管理? 设定统一的执行环境协助除错稳健熟练的程序设计师经常会在开发应用系统的过程中﹐特别加入一些除错程序或者回馈验算的程序﹐这些除错程序对于软件品质的提升有极其正面的功能。

然而开发完成的正式版本中如果不需要这些额外的程序的话﹐要想在一堆程序中找出哪些是除错用的程序并加以删除或设定为批注﹐不仅累人﹐而且容易出错﹐况且日后维护时这些除错程序还用得着。

此时如果能够应用像是$IFDEF的Compiler Directives ﹐就可以轻易的指示Delphi要/不要将某一段程序编进执行文件中。

同时﹐Compiler本身也提供了一些错误检查的开关﹐可以预先对程序中可能的问题提醒程序设计师注意﹐同样有助于撰写正确的程序。

版本分类除了上述的除错版本/正式版本的分类之外﹐对于像是「试用版」「普及版」「专业版」的版本分类﹐也可以经由Compiler Directive的使用﹐为最后的产品设定不同的使用权限。

其它诸如「中文版」「日文版」「国际标准版」等全球版本管理方面﹐同样也可以视需要指示Delphi 特别连结哪些资源档或者是采用哪些适当的程序。

以上的两则例子中﹐各版本间只需共享同一份程序代码即可。

Delphi 1.0 与Delphi 2.0有许多不同之处﹐组件资源文件(.DCR)即是其中一例﹐两者的档案格式并不兼容﹐在您读过本文之后﹐相信可以写出这样的程序﹐指示Delphi在不同的版本采用适当的资源文件以利于组件的安装。

{$IFDEF WIN32}{$R XXX32.DCR}{$ELSE}{$R XXXX16.DCR}{$EDNIF}程序的重用与管理经过前文的讨论后﹐相信你已经不难看出Compiler Directives在程序管理上的应用价值。

对于原始程序的重用与管理﹐也是Compiler Directives 使得上力的地方. 举例来说: Pascal-Style字符串是Delphi 1.0与Delphi 2.0之间的明显差异﹐除了原先的短字符串之外﹐Delphi 2.0之后还多了更为方便使用的长字符串﹐同时﹐系统也额外提供了像是Trim()这样的字符串处理函式。

假如您有一个字符串处理单元必须要同时应用于Delphi 1.0 与2.0的项目时﹐编译指示器可以帮你的忙。

此外﹐透过像是{$I xxxx} 这样的Compiler Directives﹐我们也可以适当的含入某些程序, 同样有助于切割组合我们的程序或编译设定。

设定一致的执行环境项目小组的成员间﹐必须有共同的环境设定﹐我很难预料一个小组成员间彼此有不同的{$B}{$H}{$X}设定﹐最后子系统在并入主程序时会发生什么事。

此外, 当您写好一个组件或单元需要交予第三者使用时, 使用编译指示器也可以保证元件使用者与您有相同的编译环境。

使用Compiler Directives指令语法Compiler Directives从外表看起来与批注颇为类似, 与批注不同的是:Compiler Directives的语法格式都是以「{$」开始, 不空格紧接一个名称(或一个字母)表明给Compiler的特别指示, 再加上其它的开关或参数内容,最后以右大括号作为指令的结束, 例如:{$B+}{$R-}{$R MyCursor.res}同时, 就如同Pascal的变量名称与保留字一样, Compiler Directives也是不区分大小写的。

从指令的语法格式来说Compiler Directives﹐可以进一步分类成以下三种格式:?开关指令(Switch directives)这类指令都是单一字母以不空格的方式连接「+」或「-」符号; 或者是开关名称以一个空格后连接「ON」或「OFF」来表示作用/关闭某一个编译指示开关。

例如:{$A+}{$ALIGN ON}开关型的编译指令不一定要分行写, 它们可以组合在同一个编译指示的批注符号之间,但必须以逗号连接, 而且中间不可以有空格, 例如:{$B+,H+,T-,J+}光标停留在程序编辑器的任一位置时按下Ctrl+O O, 完整的Compiler Directives将会全部列于Unit的最上方。

?参数指令(Parameter directives)有些Compiler Directives需要在编译名称后面连接自定的参数(文件名称或指定的记忆体大小), 例如: {$R MyCursor.res}, 即在指示Delphi在编译连结时,含入「MyCursor.res」这个资源档。

?条件指令(Conditional directives)指示Compiler在编译的过程中, 按我们设定的条件, 选择性的采用/排除不同区域的程序代码。

以下是一个条件编译的例子, 第一与第三列是写给Compiler看的,指示Compiler在__DEBUG这个条件名称完成定义的情况才编译ShowMessage()这列程序;反之, 如果__DEBUG 当时没有定义的话, 这段程序几乎与批注无异, Compiler对它将视而不见。

{$IFDEF __DEBUG}ShowMessage(IntToStr(i));{$ENDIF}如何从IDE改变Compiler directives设定?从Delphi的IDE程序整合发展环境, 我们很方便的就可以修改各个compiler directives的设定, 方法是:从Delphi IDE主选单: Project/Options/Compiler, 直接核选/取消各个CheckBox。

值得注意的是, 改变一个项目的Compiler directives并不会影响其它的项目, 换言之,各个项目都保有自己一套编译指示。

假如您希望其它的项目也采用相同一套的Compiler directives, 在上述Project Options对话盒的左下方有一个「Default」选项, 选取这个CheckBox之后, 虽然对于既有的项目没有作用, 但未来新的项目都将可以采用这组设定作为默认值。

将Compiler directives写入程序透过Delphi的整合环境设定Compiler directives的确十分简便, 但是许多情况下我们仍然需要将Compiler directive直接加到程序中。

至少有两个原因支持我们这么作:局部控制编译条件在Project/Options/Compiler中所作的设定, 影响所及是整个项目, 如果某一段程序要特别使用不同的编译设定, 就必须直接将编译指示加到程序中。

下列这段取自Online Help的程序范例, 即应用了{$I}编译指令局部控制在发生I/O错误时不要举发例外讯息, 这样, 我们就可以编译出一支在这段程序区域中不会产生I/O例外讯息的档案侦测函数。

function FileExists(FileName: string): Boolean;varF: file;begin{$I-}AssignFile(F, FileName);FileMode := 0; ( Set file access to read only }Reset(F);CloseFile(F);{$I+}FileExists := (IOResult = 0) and (FileName <> '');end; { FileExists }程序的可移植性我们都可能会用到其它公司或个人创作的unit或component, 也可能分享程序给其它人, 换句话说, 单元或程序可能会在不同的机器上编译, 直接将Compiler directives加入程序, 不仅可以免去程序使用前需要特别更改IDE的麻烦, 更重要的是解决了各个单元间要求不同编译环境的歧异。

注意事项Compiler directives的作用与影响范围如同变量的可见范围与生命周期, 在我们使用Compiler Directives 时也必须注意各个Compiler Directives 的作用范围.Compiler Directives的作用范围可分为以下两种:全域的全域的Compiler Directives, 影响所及是整个项目; 我们稍早前提到经由Delphi IDE改变Compiler directives的方式就属于全域的设定。

区域的而区域的Compiler Directives 影响所及只从Compiler Directives 改变的那一行开始, 直到该程序单元(Unit)的结束或另一个相同的Compiler Directives 为止,对其他的程序单元并没有影响。

也就是说, 如果在unit中特别加入Compiler directives, Compiler会优先采用区域的设定, 然后才是属于项目层级的全域设定。

值得一提的是, 在程序中直接加入Compiler directives的最大作用范围也只限于当时那个单元而已, 对其他单元并没有任何影响, 即使是以uses参考也是一样。

也就是说,我们可以透过uses参考其它unit公开的变量与函式, 但是各个unit的编译指令并不会互相参考。

这项独立的性质, 使得unit之间编译环境的设定与关系变得十分简洁, 例如Delphi 2.0的VCL都是在{$H+}的情况下编译的, 因此, VCL中的字符串都是以长字符串的型态编译而成的, 有了这项编译指令独立的特性, 不论我们Prject中的设定为何, 这些在VCL中定义过的字符串都是长字符串。

我们的Project也不会因为uses了VCL中的unit而改变了自己的设定。

因此, 在我们移交程序到网络上时, 大可以放心的在程序中加入必要的Compiler directives, 别担心, 即使别的unit以uses参考了我们的程序, 也不影响它自己原来的设定。

相关文档
最新文档