import指令
import 创建两个标题文件来重新构造C++源代码内的类型库内容。主要标头文件类似于生产有Microsoft“接口定义语言”(MIDL)编译器生成的文件,但是是使用附加的编译器生成的代码。“主要标头文件”具有与类库相同的基名称以及.TLH扩展。次要头文件具有与类库相同的基名称,并包含有.TLH扩展。它在主要头文件中包含编译器生成的成员函数的实现并包含(#include)。 ### Import 指令详解 #### 一、概述 `import` 指令是C++编程语言中用于从类型库文件(如 `.tlb`, `.olb`, 或 `.dll` 文件)导入类型定义到源代码的一个特殊指令。通过 `import` 指令,程序员能够方便地使用来自COM组件或其他类型库中的接口、类和数据类型。 #### 二、基本语法与使用 `import` 指令的基本语法如下: ```cpp #import "filename" [attributes] ``` 或者 ```cpp #import <filename> [attributes] ``` 其中: - **filename** 表示要导入的类型库的名称。它可以是一个文件名,也可以是一个 `progid` 或者类型库的 `libid`。 - **attributes** 是一个或多个由逗号或空格分隔的特性,用于控制导入行为。 #### 三、类型库文件 类型库文件包含了COM组件或其他类型的元数据,如接口定义、类定义等。当使用 `import` 指令时,这些元数据会被转换成相应的C++代码。 #### 四、`import` 指令特性详解 - **no_namespace**: 当使用此特性时,类型库中的所有类型都不会包装在一个命名空间中,这有助于避免命名冲突。 - **raw_interfaces_only**: 如果指定此特性,那么生成的接口将是“裸”的,即不会自动添加派生自 `IUnknown` 的基类。 - **rename**: 此特性允许用户重命名类型库中的特定标识符,以避免与现有代码中的标识符冲突。例如 `rename("EOF", "adoEOF")` 表示将类型库中的 `EOF` 重命名为 `adoEOF`。 #### 五、`filename` 参数解析 - **文件名**: 可以是一个包含类型库的文件名,如 `.dll`、`.tlb` 或 `.olb` 文件。 - **ProgID**: 如 `Excel.Application` 这样的标识符。 - **LibID**: 类型库的唯一标识符,例如 `{12341234-1234-1234-1234-123412341234}`。 - **可执行文件**: 如 `.exe` 文件。 - **库文件**: 包含类型库资源的 `.dll` 文件,如 `.ocx`。 - **复合文件**: 符合文件格式的类型库。 #### 六、搜索路径 - **带引号的文件名**: 预处理器首先在包含 `#import` 语句的文件所在目录中搜索类型库文件,然后在编译器的其他指定路径中搜索。 - **带尖括号的文件名**: 预处理器会在环境变量 `PATH` 和 `LIB` 定义的路径中搜索类型库文件。 #### 七、生成的头文件 `import` 指令会生成两个标题文件: - **主要标头文件**:通常包含类型定义和声明,其扩展名为 `.TLH`。 - **次要标头文件**:包含编译器生成的成员函数的实现,也具有 `.TLH` 扩展名。这些文件通过 `#include` 被包含在主要标头文件中。 这两个文件都会被保存在由 `/Fo` 选项指定的输出目录中,并且可以被编译器像普通头文件一样编译。 #### 八、优化与重构 - **缓存机制**:当编译器处理 `#import` 时,它会首先检查生成的头文件是否存在且是最新的。如果文件存在且未过期,则不会重新生成。 - **最小化重新生成**:`#import` 指令支持最小化重新生成机制,这意味着只有当类型库文件更改时才会重新生成相关的头文件。 - **预编译头文件**:`#import` 指令可以放在预编译头文件中,以减少编译时间。 #### 九、路径依赖 编译器为每个处理过的类型库生成的 `.TLH` 文件中,会包含指向其他类型库的完整路径,这样可以确保类型之间的正确引用。 #### 十、错误处理 如果类型库中引用了其他类型库,但编译时出现了类型定义缺失的错误,可以通过查看 `.TLH` 头文件中的注释来找到需要先导入的类型库,从而解决问题。 #### 十一、总结 `import` 指令是C++中非常有用的工具,它极大地简化了与COM组件和其他类型库的交互过程。通过合理的使用 `import` 指令及其特性,开发人员可以更加高效地利用现有的类型库资源,提高代码复用性和可维护性。