object-c中#import #include @class的区别

本文详细介绍了Objective-C中三种常见的类导入方式:#include、#import及@class的区别与使用场景。探讨了每种导入方式的特点及其对程序效率的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在ObjC程序源文件中,要使用外部的类,需得先将类导入到源文件中。在Objective-C中导入类有三种方法,分别是#include、#import和@class。这三种我们在合适使用呢?又有什么差别呢?

#include方法是继承自C语言的,前面已经说过,通过#include方法可以导入类,但是不能判断导入类是否重复,如果要判断,那么就需要使用#ifdef进行宏判断,非常麻烦!

#import方法是Objective-C引入的,跟#include意义上是一样的,但是可以自行判断是否重复导入,如果已经导入了,那么就忽略掉。

#import和#include导入类有两种方法:#import <>和#import “”。前面一个使用<>尖括号使用时,表示引入的是系统类,会直接到库里查找。如果使用””双引号,表示引入自定义类,系统会先查找当前目录,然后查找path目录,最后再在库中进行查找。

@class方法

使用@Class+类名,其实只是告诉编译器,这是一个类,而不是加载类头文件,所以编译器不会处理这个类的结构,就不知道类具有的属性和方法。

使用@class指令提高了程序效率,原因如上,编译器只需要知道有这样一个类名,而不处理细节。但是,在使用中就不能调用类的方法了,如果使用了,会出现如下错误:

Receiver type ‘Person’ for instance message is a forward declaration
Proerity ‘name’ cannot be found in forward class object ‘Person’

导入格式:

@class ClassName

### 使用 `#import` 导入 DLL 并设置 `no_namespace` 属性 在 C++ 中,可以通过 `#import` 指令导入类型库文件(通常是 `.dll` 文件),并指定属性以控制生成的代码的行为。如果希望禁用命名空间,则可以在 `#import` 指令中使用 `raw_interfaces_only` 和 `no_namespace` 属性。 以下是实现方法: #### 在 C++ 中导入 `dm.dll` 并禁用命名空间 ```cpp #import "dm.dll" raw_interfaces_only no_namespace named_guids ``` 上述指令的作用如下: - **`raw_interfaces_only`**: 只生成原始接口定义,不生成智能指针类[^1]。 - **`no_namespace`**: 不创建任何命名空间,所有类型的名称都直接可用而无需限定前缀。 - **`named_guids`**: 将 GUID 定义为常量变量而不是嵌入到类型定义中。 这样,在后续代码中可以直接使用 `dm.dll` 提供的类型和函数名,而不必加上命名空间前缀。 --- #### 如果是在 C# 中调用 `dm.dll` C# 本身并不支持 `#import` 指令,而是通过 P/Invoke 或 COM Interop 来访问外部动态链接库中的功能。对于已有的 C++ 类型库,通常需要先将其注册为 COM 组件,然后在 Visual Studio 的 “添加引用” 对话框中找到该组件并引入项目。 为了简化操作流程,可以按照以下方式处理: 1. 注册 `dm.dll` 作为 COM 组件(假设它是一个 COM 库)。这可能需要管理员权限运行命令提示符,并输入以下命令: ```cmd regsvr32 dm.dll ``` 2. 在 C# 项目中右键点击“引用”,选择“COM”选项卡下的 `dm.dll` 添加进来。 3. 设置 `using` 命名空间时忽略默认生成的命名空间。例如,如果不想显式声明命名空间,可直接实例化对象或调用静态方法。 注意:如果不希望通过命名空间访问,也可以手动调整生成的互操作程序集(Interop Assembly)的内容,但这通常不是推荐的做法[^2]。 --- #### 示例代码片段 ##### C++ 实现示例 ```cpp #include <iostream> // 导入 dll 并禁用命名空间 #import "dm.dll" raw_interfaces_only no_namespace named_guids int main() { // 创建 COM 对象实例 IMyInterface* pInterface = nullptr; HRESULT hr = CoCreateInstance(CLSID_MyClass, NULL, CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&pInterface); if (SUCCEEDED(hr)) { std::cout << "成功加载 DM.DLL!" << std::endl; // 调用接口的方法 pInterface->SomeMethod(); // 清理资源 pInterface->Release(); } else { std::cerr << "无法加载 DM.DLL." << std::endl; } return 0; } ``` ##### C# 实现示例 ```csharp using System; using System.Runtime.InteropServices; class Program { static void Main(string[] args) { Type type = Type.GetTypeFromProgID("DM.MyObject"); object obj = Activator.CreateInstance(type); Console.WriteLine("成功加载 DM.DLL!"); } } ``` --- ### 注意事项 - 确保目标平台上的开发环境已经安装了必要的工具链以及依赖项。 - 若 `dm.dll` 是纯 Win32 动态库而非 COM 组件,则需借助其他手段(如编写中间层封装器)才能被 .NET 应用程序所识别。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值