Xcode:引用 C++来自 Objective-C 项目的项目

发布于 2024-11-27 00:26:54 字数 1108 浏览 0 评论 0原文

我开始为此抓狂,所以是时候在这里发帖了!

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ま柒月 2024-12-04 00:26:55

感谢所有给我建议的人。

从头开始重新创建我的项目后,我通过摆弄和逻辑来找到解决方案。请注意,至少在我的情况下,不需要使用 #ifdef __cplusplus,也不需要任何其他预处理器指令。仅需要更改文件后缀(如下详述)。

过程如下:

在 XCode 4 中创建 C++ 静态库并包含/链接 Objective-C 库(例如 iOS 应用程序)

  • 在 XCode 4 中创建一个 Cocoa Touch 静态库类型的新项目。此后我们将该项目称为“CProj”。
  • 在 CProj 工作区中根据需要创建/导入尽可能多的 C++ 类。文件名不需要特殊后缀 - 我的所有文件都是 .h 和 .cpp。
  • 在 XCode 中创建/打开任何 Objective-C 项目,例如 iOS 应用程序。此后我们将该项目称为“ObjProj”。
  • 在 Finder 中找到 CProj.xcodeproj(通常为 /Documents/CProj/CProj.xcodeproj),将其拖到 XCode 项目导航器顶部的可见 ObjProj 项目图标上(XCode 中左侧可见的文件/文件夹层次结构)。现在,CProj 作为 ObjProj 中的嵌套项目。
  • 左键单击 Project Navigator 中的 ObjProj 项目图标,右侧会出现一个新窗格,左键单击此窗格中的 Build Phases。
  • 在“目标依赖项”下,单击“+”图标,然后选择列出的 CProj 项目下方的 CProj 库图标。单击“确定”。
  • 在 Link Binary With Libraries 下,单击“+”图标,然后从显示的窗口顶部的 Workspace 可折叠文件夹中选择 CProj 库图标。

文件重命名规则

  • 在 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:

  • In XCode 4 create a New Project of type Cocoa Touch Static Library. Hereafter we shall refer to this project as 'CProj'.
  • In CProj workspace create/import as many C++ classes as required. No special suffix for filenames is necessary - all my files are .h and .cpp.
  • In XCode create/open any Objective-C project e.g. iOS app. Hereafter we shall refer to this project as 'ObjProj'.
  • Find CProj.xcodeproj in Finder (typically /Documents/CProj/CProj.xcodeproj), drag it onto the visible ObjProj project icon at the top of your XCode Project Navigator (visible file/folder hierarchy on left side in XCode). This now places CProj as a nested project within ObjProj.
  • Left click ObjProj project icon in Project Navigator, a new pane emerges to the right, left click Build Phases in this pane.
  • Under Target Dependencies click '+' icon and select CProj library icon below listed CProj project. Click OK.
  • Under Link Binary With Libraries click '+' icon and select CProj library icon from within Workspace collapsible folder at top of window presented.

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.

故人的歌 2024-12-04 00:26:55

听起来你的问题的症结是这样的:

编译器是否无法识别 MyClass.hh 不是 Objective-C++
Objective-C?

编译器无法识别 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:

Is the compiler not recognising that MyClass.hh is Objective-C++ not
Objective-C?

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文