## 修饰扩展
> E64的修饰符号一律为在备注开始的位置以中括号[]表示。共有以下修饰方式。
> 下图为右击即可出现以下菜单

| 修饰符号 | 解释 |
| --- | --- |
| [*] | 修饰一个变量或参数为指针类型可以修饰多级指针[***] 。|
| [不初始化] | 修饰一个局部变量 定义后不进行初始化 。|
|[__stdcall]|修饰一个子程序 或DLL调用声明为stdcall约定。|
|[_cdecl]|修饰一个子程序 或DLL调用声明为cdeclcall约定。|
|[__fastcall]|修饰一个子程序 或DLL调用声明为fastcall约定。|
|[联合体]|修饰一个自定义数据类型为联合体类型 union。|
|[嵌套]|修饰自定义数据类型成员,为结构体嵌套定义 struct。|
|[嵌套开始] [嵌套结束]|修饰一组自定义数据类型的成员,为结构体内嵌套 struct。|
|[-64]|修饰自定义数据类型成员,表示在编译为64位时,忽略该成员的定义,理解为减。用于定义兼容平台的结构体。|
|[-32]|修饰自定义数据类型成员,表示在编译为32位时,忽略该成员的定义,理解为减。用于定义兼容平台的结构体。|
|[强制保留]|用于修饰 子程序、DLL声明 表示此定义强制翻译为C代码。|
|[不要保留]|用于修饰 子程序、DLL声明、数据类型、资源、常量,表示此定义不翻译为C代码,仅作为代码提示使用。|
|[宽字符串]|用于修饰 文本常量定义,表示此文本常量是一个宽字符UNICODE|
|[原型声明]|保留 未实现 用于回调相关。|
|[C源文件]|用于修饰 文本常量定义,表示此常量的文本为一个c源文件,将参与编译,表示嵌入C源代码。|
|[C头文件]|用于修饰 文本常量定义,表示此常量的文本为一个c头文件,将参与编译,表示嵌入C头文件。|
|[SRCDIR]|用于修饰 常量头文件库文件引用,表示当前源码目录。|
示例:

>* 下面解释以下 [强制保留] 与 [不要保留] 的定义,默认情况下DLL的声明,会自动选择保留或不保留无需手动修饰定义。比如你声明了一个MessageBox 将会自动选择不保留,原因是E64默认状态下已经包括了 windows.h 等一些头文件,其中大部分数据类型、常量、API都已经被声明可以直接使用。所以这些已存在的声明会自动忽略。另外除了DLL声明外,自定义数据类型、常量将不能自动识别是否已存在于sdk的头文件中,如果你定义了一个数据类型、或常量与系统SDK里的相冲突,就需要将此声明修饰为 **[不要保留]**。
>1. [不要保留]
之所以会出现这两个修饰是因为E64默认状态下已经包括了 windows.h 等一些头文件,其中大部分数据类型、常量、API都已经被声明可以直接使用。但由于目前的E64代码提示并不完善,比如MessageBox 此声明已经存在,不需要用户进行声明,但由于没有代码提示即使强制写出来回车IDE也会报错,因此为了代码能够正常友好的提示需要声明一个仅仅用于提示,然后修饰为 **[不要保留]**,也就是在编译时将自动忽略此声明。
>2. [强制保留]
那为什么又会出现强制保留的修饰呢?在微软的SDK头文件中并不是所有的dll导出函数都被定义了,有很多未被微软定义的函数但却真实存在于dll的导出函数中,这种函数叫未文档化的函数,如ntdll.dll 的很多函数都未被公开,比如这个 RtlAdjustPrivilege。因此 **[强制保留]** 的修饰会将此声明强制翻译为C代码参与编译调用未文档化的API。
