Initializing 'AppDelegate *__strong' with an expression of incompatible type 'id

本文解决在ARC环境下,从UIApplication获取AppDelegate实例时出现的类型不匹配警告。通过强制类型转换,可以避免编译器警告,确保代码正确运行。

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

我们获取全局的AppDelegate的时候,当是ARC的时候,

当我们这样写的时候

AppDelegate *app = [UIApplication sharedApplication].delegate;

会报警告:Initializing 'AppDelegate *__strong' with an expression of incompatible type 'id<UIApplicationDelegate>

对其进行强转一下

AppDelegate *app = (AppDelegate*)[UIApplication sharedApplication].delegate;

搞定!!!

<think>我们遇到了一个错误:尝试用不兼容的类型'void'初始化'struct mtk_charger *'。错误发生在使用container_of宏时。 问题分析: container_of宏通常用于通过结构体成员的指针来获取整个结构体的指针。其基本用法是: container_of(ptr, type, member) 其中: ptr: 指向结构体成员的指针 type: 结构体的类型 member: 成员在结构体中的名称 根据错误信息,我们尝试将`work`(可能是某个结构体成员的指针)转换为`struct mtk_charger*`,但编译器提示类型不兼容。 可能的原因: 1. `work`的类型不是`struct work_struct *`,而是`void *`或其他类型,导致container_of宏展开时类型不匹配。 2. 在结构体`struct mtk_charger`中,成员`work`(或我们使用的成员)的类型与传入的`work`指针类型不匹配。 假设我们有一个结构体定义如下: struct mtk_charger { // ... 其他成员 struct delayed_work pd_ready_check_work; // 假设我们使用这个成员 }; 在work回调函数中,我们通常这样获取外层结构体指针: static void oplus_pd_ready_check_work(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); struct mtk_charger *chip = container_of(dwork, struct mtk_charger, pd_ready_check_work); // ... } 但是,如果我们的work回调函数是用于delayed_work,那么参数work实际上是delayed_work中的work成员。因此,我们需要先将其转换为delayed_work,然后再使用container_of。 然而,错误信息显示我们试图用`void`表达式初始化,这可能是由于我们没有正确转换类型。 修复步骤: 1. 确认work回调函数的参数类型:如果是delayed_work,那么参数应该是`struct work_struct *`,但我们需要的是包含它的delayed_work结构体的地址。 2. 使用正确的转换:先通过`container_of`从`work`得到`delayed_work`,然后再从`delayed_work`得到外层结构体。 但是,如果我们的结构体中直接使用`struct work_struct`(而不是`struct delayed_work`),那么就不需要先转换到delayed_work。 示例代码(使用delayed_work): static void oplus_pd_ready_check_work(struct work_struct *work) { struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct mtk_charger *chip = container_of(dwork, struct mtk_charger, pd_ready_check_work); // 或者一步到位: // struct mtk_charger *chip = container_of(work, struct mtk_charger, pd_ready_check_work.work); } 但是,第二种一步到位的方式需要知道在`mtk_charger`结构体中,`pd_ready_check_work`成员是一个`struct delayed_work`,然后我们取它的`work`成员。 然而,错误信息中我们写的是: struct mtk_charger *chip = container_of(work, ...) 如果我们的结构体成员是`struct delayed_work`,那么我们应该这样写: struct mtk_charger *chip = container_of(work, struct mtk_charger, pd_ready_check_work.work); 或者,如果我们结构体成员是`struct work_struct`(不是延迟工作),那么直接写: struct mtk_charger *chip = container_of(work, struct mtk_charger, pd_ready_check_work); 所以,我们需要检查结构体`mtk_charger`中成员的定义,以及回调函数是如何被调用的。 常见错误:在container_of宏中,第三个参数应该是成员的名字,而不是类型。 因此,请检查: 1. 结构体`mtk_charger`中工作队列成员的确切名称和类型。 2. 在container_of宏中,第三个参数是否写对了成员的名字。 如果结构体中定义的是: struct delayed_work pd_ready_check_work; 那么,在container_of中,我们应该使用`pd_ready_check_work.work`来访问内嵌的`work_struct`。 但是,container_of的第三个参数需要是成员在结构体中的名字(即`pd_ready_check_work.work`),这实际上是一个语法错误,因为container_of的第三个参数应该是一个简单的成员名,不能带点号。 因此,正确的方式是分两步: struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct mtk_charger *chip = container_of(dwork, struct mtk_charger, pd_ready_check_work); 或者,我们可以用: struct mtk_charger *chip = container_of(container_of(work, struct delayed_work, work), struct mtk_charger, pd_ready_check_work); 但这样可读性差。 另一种方法是,如果我们的结构体成员是`struct delayed_work`,我们可以这样定义回调函数: static void oplus_pd_ready_check_work(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); struct mtk_charger *chip = container_of(dwork, struct mtk_charger, pd_ready_check_work); // ... } 其中,`to_delayed_work`是内核提供的宏,实际上就是`container_of(work, struct delayed_work, work)`。 所以,请根据实际结构体定义调整。 如果问题中的代码片段是: struct mtk_charger *chip = container_of(work, ...); 并且报错是类型不兼容,那么很可能是因为`work`的类型是`void *`,而container_of宏要求第一个参数是指向结构体成员的指针,但类型必须匹配。如果`work`是`void *`,我们需要先将其转换为正确的类型,或者检查调用上下文。 但是,在Linux内核中,工作队列回调函数的参数是`struct work_struct *`,所以通常不会是`void *`。因此,请检查函数原型是否正确定义。 总结:我们需要根据结构体成员的实际类型和名称,正确使用container_of宏。 修复后的代码示例(假设结构体成员为`struct delayed_work pd_ready_check_work`): static void oplus_pd_ready_check_work(struct work_struct *work) { struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct mtk_charger *chip = container_of(dwork, struct mtk_charger, pd_ready_check_work); // 然后调用函数 mtk_chg_set_otg_src_pdo(chip->ic_dev, chip->curr_ma); } 注意:这里假设`struct mtk_charger`结构体中有一个成员`ic_dev`和`curr_ma`。 如果问题仍然存在,请检查结构体定义和实际使用的成员名。</think>### 类型不兼容错误分析与修复 #### 问题根源分析 错误信息 `initializing 'struct mtk_charger *' with an expression of incompatible type 'void'` 表明您在使用 `container_of` 宏时存在类型不匹配问题。核心原因在于: 1. **container_of宏使用错误**: ```c struct mtk_charger *chip = container_of(work, ...); ``` `container_of` 宏的第一个参数必须是**结构体成员的指针**,但您传递的 `work` 是 `struct work_struct *` 类型,与目标结构体成员类型不匹配。 2. **工作队列结构嵌套问题**: - 如果使用 `delayed_work`,它包含嵌套结构:`struct delayed_work` → `struct work_struct` - 直接使用 `work` 指针无法直接映射到外层容器结构 #### 正确使用container_of的三种方法 ##### ✅ 方法1:直接通过work_struct访问(适用于标准work) ```c struct mtk_charger *chip = container_of(work, struct mtk_charger, work_member); ``` **要求**:结构体中必须直接包含 `struct work_struct` 成员 ##### ✅ 方法2:通过delayed_work中转(推荐) ```c static void oplus_pd_ready_check_work(struct work_struct *work) { // 先转换到delayed_work struct delayed_work *dwork = to_delayed_work(work); // 再转换到目标结构体 struct mtk_charger *chip = container_of(dwork, struct mtk_charger, delayed_work_member); mtk_chg_set_otg_src_pdo(chip->ic_dev, chip->curr_ma); } ``` ##### ✅ 方法3:单步转换(需精确匹配成员) ```c struct mtk_charger *chip = container_of(work, struct mtk_charger, delayed_work_member.work); ``` ### 完整修复方案 #### 步骤1:定义正确的结构体 ```c struct mtk_charger { struct oplus_chg_ic_dev *ic_dev; int curr_ma; // 关键:必须包含work成员 struct delayed_work pd_ready_check_work; // 或 struct work_struct }; ``` #### 步骤2:正确初始化工作队列 ```c // 在probe函数中 INIT_DELAYED_WORK(&chip->pd_ready_check_work, oplus_pd_ready_check_work); ``` #### 步骤3:修复回调函数 ```diff static void oplus_pd_ready_check_work(struct work_struct *work) { - // 错误用法 - struct mtk_charger *chip = container_of(work, ...); + // 正确用法 + struct delayed_work *dwork = to_delayed_work(work); + struct mtk_charger *chip = container_of(dwork, struct mtk_charger, pd_ready_check_work); mtk_chg_set_otg_src_pdo(chip->ic_dev, chip->curr_ma); } ``` ### 类型兼容性验证表 | 实际类型 | container_of参数 | 是否有效 | 原因 | |---------|-----------------|---------|------| | `struct work_struct *` | `work_member` (work_struct) | ✅ | 直接匹配 | | `struct work_struct *` | `delayed_work_member` (delayed_work) | ❌ | 类型不兼容 | | `struct work_struct *` | `delayed_work_member.work` | ✅ | 嵌套成员访问 | | `void *` | 任何成员 | ❌ | 需要具体类型 | ### 关键注意事项 1. **成员名称必须精确匹配**: ```c // 结构体定义中的成员名 struct mtk_charger { struct delayed_work pd_work; // 必须与container_of中一致 }; // container_of使用 container_of(dwork, struct mtk_charger, pd_work); ``` 2. **Linux内核版本差异**: - 内核 ≥ 5.3:`to_delayed_work()` 已内建 - 内核 < 5.3:需自定义: ```c #define to_delayed_work(work) \ container_of(work, struct delayed_work, work) ``` 3. **类型安全增强**: ```c static_assert( offsetof(struct mtk_charger, pd_ready_check_work) == offsetof(struct mtk_charger, pd_ready_check_work.work), "Work structure mismatch" ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值