在 Objective-C 中使用外部 C++ 头文件
Posted
技术标签:
【中文标题】在 Objective-C 中使用外部 C++ 头文件【英文标题】:Use of external C++ headers in Objective-C 【发布时间】:2013-07-02 04:48:28 【问题描述】:在我的 ios 项目中,我需要使用一个用 C++ 编写的外部库。 C++ 头文件都在一个目录中。
我已将这些 C++ 标头添加到我的 Xcode 项目中,并且还指定了标头搜索路径(在构建设置中)。
问题是这些 C++ 标头使用 尖括号相互包含。这导致:
'filename.h' file not found with <angled> include, use "quotes" instead.
奇怪的是 Xcode 并没有抱怨所有的头文件。同样的标题#include'd 在一个文件中也很好,而在另一个文件中#include'd 时会出现问题。我认为这是由于这些标头#include 彼此造成的。
-
为什么搜索路径不起作用?
有没有办法在不修改这些头文件的情况下解决这个问题?
谢谢!
【问题讨论】:
你有那个 C++ 库的源代码和 Xcode 项目吗? @CouchDeveloper 不,我没有。 设置“始终搜索用户路径”构建设置有帮助吗? @MartinR 天哪,是的! :-) 把它作为答案,我会奖励。我已经删除了-I
,很好。为什么-I
不起作用?
【参考方案1】:
#include <bla.h>
用于标准库或框架头文件,以及搜索策略 与用于
的不同#include "bla.h"
参见示例
What is the difference between #include <filename> and #include "filename"?作为一种解决方法,您可以将 Xcode 构建设置“始终搜索用户路径”设置为 YES。
【讨论】:
请注意,将“始终搜索用户路径”设置为“是”可能会导致标题问题。强烈建议将其设置为 NO,这是正确的方法。它仍然只是为了向后兼容。第三方库的标头应包含在尖括号中。 @CouchDeveloper:这是一种解决方法,但您是对的,您的答案可能是更好的解决方案。 @CouchDeveloper 同意此设置应设置为 NO,但是在构建嵌入式框架的上下文中将此设置设置为 YES 有什么不希望的吗?【参考方案2】:从一个“空白”应用项目开始:
在应用程序的项目中创建一个文件夹“Libraries” - 最好作为 MyApp.xcodeproj 文件的同级,但它可以在任何地方。为每个配置(Debug、Release 等)创建子文件夹,并可能为每个架构(armv7、armv7s、arm64)创建子文件夹,除非二进制文件是包含所有架构的通用二进制存档。
获取第三方库和静态库二进制文件的头文件(对于不同的平台、配置和架构可能不止一个),并将它们移动到“库”文件夹中的相应子文件夹中(您可能需要创建):
例如,假设您有一个通用二进制文件(armv7、armv7s、arm64)以及该库的调试和发布版本: 现在,假设文件夹结构如下:
$(SRCROOT)/Libraries
Debug-iphoneos
include
ThirdParty
third_party.hh
...
libThirdParty.a
Release-iphoneos
include
ThirdParty
third_party.hh
...
libThirdParty.a
MyApp.xcodeproj
“库搜索路径”构建设置:
将“Libraries”文件夹拖到您的 Xcode 项目中。这可能会在构建设置中自动创建一个库搜索路径。请验证这一点,如果不正确,请修复它。
给定示例,为调试和发布配置添加以下库搜索路径:
调试:库搜索路径:$(SRCROOT)/Libraries/Debug-iphoneos
发布:图书馆搜索路径:$(SRCROOT)/Libraries/Release-iphoneos
对于特定的配置和目标平台对,您可能有不同的库搜索路径。相应地在构建设置中设置不同的路径。
“标题搜索路径”构建设置:
给定示例,将以下标头搜索路径添加到调试和发布配置:
调试:标头搜索路径:$(SRCROOT)/Libraries/Debug-iphoneos/include
发布:标题搜索路径:$(SRCROOT)/Libraries/Release-iphoneos/include
同样,对于特定的 Config/Target 对,您可能有不同的路径 - 尽管标头可能相同。
通过将 -lc++
添加到 Other Linker Flags 构建设置,将您的应用与 C++ 标准库链接。
在您的文件中导入标头,如下所示:
#import <ThirdParty/third_party.hh>
【讨论】:
这很有帮助,因为在我的情况下,该错误取决于目标。 史诗,我第一次可以使角度包括使用我项目中的第 3 方库,因为我想修补它。谢谢。【参考方案3】:在 Xcode 9 中,我需要将头文件路径添加到 Header Search Paths
构建设置,而不是 User Header Search Paths
。
Xcode 会将User Header Search Paths
附加到编译命令作为-iquote
选项,但附加Header Search Paths
作为-I
选项。这是关键的区别。
【讨论】:
感谢您指出这一点。 (不过我没时间检查,我相信你。)【参考方案4】:在 XCode 中,将“用户标题搜索路径”设置为指向您的库目录后,您还必须确保将名为“始终搜索用户路径”的字段设置为“是”
这解决了我遇到的问题:使用 包含找不到
【讨论】:
【参考方案5】:我的两分钱用于 OSX / mysql。 (顺便问一下,为什么在 mysql 中虚假使用 ......无论如何......)
根据 Xcode 11 警告,“强烈建议禁用它。”,
我更喜欢修补另一个设置,将“始终搜索用户路径”保留为“否”。
我设置:
HEADER_SEARCH_PATHS = "/usr/local/mysql/include"。
链接器:
我) 如果出现链接错误,通常在“/usr/local/mysql/lib”中添加“libmysqlclient.a”,只需从Finder中拖动即可)
II:你可能会遇到最严重的错误......
"/usr/local/lib/libmysqlclient.21.dylib: (/usr/local/lib/libmysqlclient.21.dylib) 中的代码签名在使用库验证的进程中无效: 映射进程和映射文件 (非平台)具有不同的团队 ID”
因为那个库没有签名。只需在 Entitlemens 中:
(在 XML 中): ..
<dict>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
...
【讨论】:
以上是关于在 Objective-C 中使用外部 C++ 头文件的主要内容,如果未能解决你的问题,请参考以下文章