Xcode:引用 C++来自 Objective-C 项目的项目
我开始为此抓狂,所以是时候在这里发帖了!
我在 XCode 中有一个 C++ 项目,作为命令行工具构建。所有 .cpp 文件已重命名为 .mm,有一个 .hh 和几个 .h 标头。我已指定“将源编译为 ->”构建设置中的“Objective-C++”。
我有另一个用于 iOS 应用程序的 XCode 项目。这被设置为“编译源为->”根据文件类型'。我无法将其设置为将所有内容编译为 Objective-C++,因为项目的某些部分不会编译为 Obj-C++。
我希望在 iOS 应用程序中使用我的 C++ 项目中的一个类,它由文件 MyClass.hh、MyClass.mm 组成;它们只是 .h 和 .m,但我对它们进行了重命名,希望能够解决这个问题。
我将我的cpp项目拖到iOS项目中。然后,我在 iOS 构建阶段添加了一个目标依赖项以指向 cpp CLI 应用程序。
在 MyClass.hh 中,我有
#include "../path/to/CppProject/ImportAll.h"
.. 这是一个头文件,它连续“包含 cpp 项目中的所有头文件”。然后我继续我的工作,在 MyClass.hh 中创建一个属性,它是一个指向 cpp 对象的指针,并在 MyClass.mm 中创建对 cpp 类的各种引用。
但该死的事情就是无法编译 - 我收到大量与我的 cpp 类相关的消息,如下所示:
MyCPPFile.h:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
编译器是否无法识别 MyClass.hh 是 Objective-C++ 而不是 Objective-C?我是否应该有一个目标依赖项,它是一个库,而不是指向这个 CLI 应用程序?
我用谷歌搜索了一段时间试图解决这个问题。我见过有人使用
#ifdef __cplusplus
.mm 或必须将文件重命名为 .mm 才能正常工作,但在其他情况下,人们只是说他们拖放项目没有任何问题。
有人可以启发我,并解释我应该执行哪些关键步骤才能完成这项工作吗?我将非常感激!谢谢。
I'm beginning to tear my hair out over this, so it's time to post here!
I have a C++ project in XCode, built as a Command Line Tool. All .cpp files have been renamed as .mm, there is one .hh and a few .h headers. I've specified 'Compile Sources As -> Objective-C++' in Build Settings.
I have another XCode project for an iOS app. This is set to 'Compile Sources As -> According to File Type'. I can't set it to compile everything as Objective-C++ since some parts of the project won't compile as Obj-C++.
There is one class in the iOS app where I wish to utilise my C++ project, and it consists of files MyClass.hh, MyClass.mm; they were simply .h and .m but I renamed them in the hope of remedying this problem.
I dragged my cpp project into the iOS project. I then added a Target Dependency in the iOS Build Phases to point to the cpp CLI application.
In MyClass.hh I have
#include "../path/to/CppProject/ImportAll.h"
..which is a header file that successively 'include's all headers from the cpp project. I then go about my business, creating one property within MyClass.hh which is a pointer to a cpp object, and various references within MyClass.mm to cpp classes.
The darn thing just won't compile though - I get a ton of messages relating to my cpp classes like this:
MyCPPFile.h:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
Is the compiler not recognising that MyClass.hh is Objective-C++ not Objective-C? Should I have a target dependency which is a library instead of pointing to this CLI app, perhaps?
I've googled around for a while trying to solve the problem. I've seen references to people using
#ifdef __cplusplus
or else having to rename files to .mm to get things working, but in other cases people simply say they drag and drop projects across with no issues.
Can someone please enlighten me, and explain what key steps I should be performing to make this work? I'd be very grateful! Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
感谢所有给我建议的人。
从头开始重新创建我的项目后,我通过摆弄和逻辑来找到解决方案。请注意,至少在我的情况下,不需要使用 #ifdef __cplusplus,也不需要任何其他预处理器指令。仅需要更改文件后缀(如下详述)。
过程如下:
在 XCode 4 中创建 C++ 静态库并包含/链接 Objective-C 库(例如 iOS 应用程序):
文件重命名规则
在 ObjProj 中包含 CProj 标头的情况下,使用路径回溯来识别导入,例如 #include "../../MyProj/MyImport.h" 到向后的第 2 步目录进入MyProj文件夹。
任何包含 CProj 标头的 ObjProj 实现文件都必须从 .m 重命名为 .mm 。任何包含 CProj 标头的 ObjProj 标头文件都必须从 .h 重命名为 .hh 。
任何包含后缀现在为 .hh(上述步骤的结果)的文件的 ObjProj 文件都必须以相同的方式重命名。
一个例子:
假设您有文件 Ah、Am、Bh,BmAm 导入 Bh,并且 Bh 包含一个或多个 CProj 标头。 Bm 包含类型引用,使用通过 Bh 包含的 CProj 类。
首先重命名为Bh -> B.hh 因为它包含包含。
然后Bm-> B.mm 因为它包含对 CProj 的类型引用(不需要包含,因为 Bh 已经完成了它们)。
然后Am-> A.mm 因为包含 Bh 的 Am 现在包含重命名的文件 B.hh 。
PS 请注意,C++ 库不喜欢在应该自动重建的时候自动重建 - 我经常不得不这样做从 ObjProj 中更新 CProj 后,在 ObjProj 中“清理”然后“构建”。
Thanks to everyone who gave me suggestions.
Having created my projects anew from scratch, I fiddled and logic-ed my way to the solution. Note that - at least in my case - no use of #ifdef __cplusplus was required, nor any other preprocessor directive. Only file suffix changing is essential (as detailed below).
Here's the process:
Create C++ Static Library and Include/Link with Objective-C Library (e.g. iOS app) in XCode 4:
File Renaming Rules
Where including a CProj header in ObjProj, use path backtracking to identify import, e.g. #include "../../MyProj/MyImport.h" to step 2 dirs backwards then step into MyProj folder.
Any ObjProj implementation file including a CProj header must be renamed from .m to .mm . Any ObjProj header file including a CProj header must be renamed from .h to .hh .
Any ObjProj file including a file whose suffix is now .hh (consequence of step above) must be renamed in the same manner.
An example:
Consider you have files A.h, A.m, B.h, B.m.
A.m imports B.h, and B.h includes one or more CProj headers. B.m includes type references, using CProj classes included via B.h .
First renaming is B.h -> B.hh since it contains includes.
Then B.m -> B.mm since it contains type references to CProj (no includes necessary since B.h has already done them).
Then A.m -> A.mm since A.m which contained an include for B.h now has an include for the renamed file, B.hh .
P.S. Note that the C++ library doesn't like to auto-rebuild when it should - I often have to 'Clean' then 'Build' in ObjProj after updating CProj from within it.
听起来你的问题的症结是这样的:
编译器无法识别 MyClass.hh 是 Objective-C++ 代码。或任何其他代码; 编译器永远不会看到MyClass.hh(很可能)。
按照约定,默认情况下头文件不会传递给编译器。只有源文件(.cpp、.m 等)是——在这些文件上运行的预处理器会产生一个翻译单元,其中包含原始源文件以及所有包含的标头和已解析的宏。
所以问题是您可能有一个导入 MyClass.hh 的 .mm 源文件,该文件又包含 C++ 头文件。但是编译器正在尝试将生成的翻译单元编译为 Objective-C++,并在该标头中遇到一些特定于 C++ 的内容。事实上,我怀疑这个问题与额外的目标依赖项完全无关,因此您已经进行了设置:我认为您可以使用一个非常简单的包含标头的 Objective-C++ 应用程序来最少地重现它。你应该尝试一下,看看,它要么证实我的理论(毕竟我只是猜测,因为你没有提供足够的来源让我确定),要么表明问题出在其他地方。
解决方案可能是使用像
#ifdef __cplusplus
这样的预处理器保护(有一个有用的预定义符号目录此处)向 Objective-C++ 编译器隐藏特定于 C++ 的代码(或者在某些情况下相反)。请注意,根据标头的实际内容,这可能很难甚至不可能做到。It sounds like the crux of your problem is this:
The compiler is not recognizing that MyClass.hh is Objective-C++ code. Or any other code; the compiler never sees MyClass.hh (in all likelyhood).
By convention, header files are never passed to the compiler by default. Only the source files (.cpp, .m, et cetera) are -- the preprocessor that is run on those files results a translation unit that contains the original source file plus all the included headers and resolved macros.
So the problem is that you probably have a .mm source file that imports MyClass.hh, which in turn includes the C++ header file. But the compiler is trying to compile the resulting translation unit as Objective-C++ and encountering some C++-specific stuff in that header. In fact, I suspect that this problem has nothing at all to do with the additional target dependencies and such that you've got set up: I think you could reproduce it minimally with a very simple Objective-C++ application that includes the header. You should try that and see, it will either confirm my theory (after all I'm just speculating since you haven't shown enough source for me to know for sure) or indicate that the problem is elsewhere.
The solution is probably to use preprocessor guards like
#ifdef __cplusplus
(there's a useful catalog of predefined symbols here) to hide the C++-specific code from the Objective-C++ compiler (or the other way around in some cases). Note that this may be difficult to impossible to do based on the actual content of the header.