【问题标题】:Objective-C++ importing C++ class fails, cassert not foundObjective-C++ 导入 C++ 类失败,未找到 cassert
【发布时间】:2012-08-21 07:07:07
【问题描述】:

所以我想在我的 cocos2d + box2d 项目中公开一个 Box2D (C++) 指向其他 Objective-C++ 类的指针。我在我的接口中声明了一个方法“getWorld”,它引用了 C++ 类 b2World 并导入了 Box2D.h。我项目中的所有文件都是 .mm 扩展名,我得到以下编译错误:

In file included from DebugDrawLayer.mm:2:
In file included from World.h:10:
In file included from external/Box2d/Box2D/Box2D.h:34:
external/Box2d/Box2D/Common/b2Settings.h:22:10: fatal error: 'cassert' file not found
#include <cassert>

我猜 Box2D.h 不知何故被编译为 C 而不是 C++,但我不明白这是怎么发生的。根据日志,包含链显然是从 .mm 文件开始的。

更新:

日志显示 World.mm(之前编译)清楚地编译为 Objective-c++

CompileC Objects-normal/i386/World.o World.mm normal i386 objective-c++ com.apple.compilers.llvm.clang.1_0.compiler 

但是对于 DebugDrawLayer.mm 它说的是objective-c

CompileC Objects-normal/i386/DebugDrawLayer.o DebugDrawLayer.mm normal i386 objective-c com.apple.compilers.llvm.clang.1_0.compiler

这两个文件都设置为默认值 - Objective-C++ 源代码。什么给了..?

【问题讨论】:

  • 在 Xcode 主编辑器中打开 DebugDrawLayer.mm。然后打开文件检查器(视图 > 实用程序 > 显示文件检查器)。在文件检查器中有一个文件类型弹出菜单。选择什么文件类型?是“默认 - Objective-C++ 源代码”吗?
  • @robmayoff 是的,它是“默认 - Objective-C++ 源代码”。这里似乎有一些黑魔法在起作用:)

标签: objective-c ios cocos2d-iphone objective-c++ box2d-iphone


【解决方案1】:

这似乎是 Xcode4 中的一个主要错误,与编译器设置无关 - 只是 Xcode 内部。


更新:

我最终找到了根本原因。是的,这是 Xcode/LLVM 中的一个错误。它以错误的顺序编译文件,然后覆盖自己的设置,并自行中断。苹果的技术支持太无能,甚至无法理解这个问题,所以我怀疑他们很快就会修复这个错误。

(注意:跳过此部分,并在下面查看我的原始答案,这给出了一个蛮力但非常快速的解决方案)

会发生什么......如果编译器“看到”一个 C++ 头文件在处理一个 C 类......然后它(内部)将该头文件标记为“C”(即使这是几乎不可能)。

稍后,当它回到那个头文件,尝试用 C++ 编译它时,它发现它已经告诉自己头文件是“C”(因为它非常愚蠢)......并且立即崩溃。

正确解决方案(需要大量时间和精力)是检查项目中的每个 C 文件,并检查(手动,因为 Xcode 很烂)对每个头文件的每个引用 --并且,对于每一个,它导入的每个头文件......等等。

(这可能需要几个小时)

...直到找到导致 C 文件“看到”C++ 标头的导入链。

所有这些都应该是自动化的(但不是)。并且根本问题不应该发生(如果 Xcode 编写正确的话)。


我尝试了网上其他地方列出的所有方法,大多数解决方案都是“不断删除/添加文件,如果幸运的话,Xcode 最终会自行修复”。

我不走运。唯一有效的是:

  1. 转到为您的项目构建设置
  2. 找到“将源编译为”设置
  3. 将其设置为“Objective-C++”
  4. 重新构建

实际的名称/值是:“GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp” - 所以我猜这回避了 Xcode(坏了!)的内部逻辑。

【讨论】:

  • 不,我是说它应该尊重它自己的设置,它应该尊重编译器,它应该尊重编程语言。用 C 编译器编译 C++ 文件(它知道是 C++)只是......各种错误。
【解决方案2】:

我遇到了同样的错误,我刚刚将我的一个类(我称之为 box2d 类)从 className.m 重命名为 className.mm,现在它可以工作了。

【讨论】:

    【解决方案3】:

    我在 Cocos2D/Box2D 项目中遇到了这个问题,直到我将项目中的所有 .m 文件(当然不包括 Cocos2D 中的文件)重命名为 .mm 以将它们编译为 Objective -C++。

    我猜@Adam 的解决方案也可以,但我更喜欢将编译设置保留为“根据文件类型”,感觉更干净。

    【讨论】:

    • 问题是:Apple 不尊重“根据文件类型”设置。基本上:该设置是一个谎言。所以,是的......你可以把它留在那个设置,但你得到的只是“更清洁”的错觉。
    【解决方案4】:

    从项目中删除 DebugDrawLayer 然后重新添加它解决了这个问题。也许在构建阶段设置文件中有一些奇怪的编译器设置,从未检查过。

    【讨论】:

      【解决方案5】:

      实际上正确的解决方案是将您的代码放入:

      #if __cplusplus
      
      // … your code … 
      
      #endif // __cplusplus
      

      【讨论】:

        【解决方案6】:

        我在Prefix.pch 中有#import "Box2D.h" 时遇到了这个问题。我将#import "Box2D.h" 更改为在每个使用它的文件中。

        【讨论】:

          猜你喜欢
          • 2016-09-03
          • 1970-01-01
          • 1970-01-01
          • 2014-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-20
          相关资源
          最近更新 更多