如何在FireBreath项目中添加Objective C代码?

4
我正在编写一个Mac OS浏览器插件,它将在状态栏中放置一个状态栏图标,用户可以使用它来与浏览器插件交互。我已经成功地在XCode 4.4.1中构建了一个FireBreath 1.6项目,并可以在浏览器中安装它。然而,FireBreath使用C ++,而现有的大多数Mac OS库都是用Objective C编写的。
在/Mac/projectDef.make文件中,我添加了Cocoa Framework和Foundation Framework,如此处所建议的以及我在互联网上找到的其他资源。
target_link_libraries(${PROJECT_NAME}
    ${PLUGIN_INTERNAL_DEPS}
    ${Cocoa.framework} # added line
    ${Foundation.framework} # added line
)

我重新运行了prepmac.sh,期望在XCode中创建一个新项目,其中包括我的.mm和.m文件; 但是,它们似乎被忽略了。我只看到.cpp和.h文件。我在projectDef.make文件中添加了这些文件的规则,但似乎没有任何区别。
file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
    Mac/[^.]*.cpp
    Mac/[^.]*.h
    Mac/[^.]*.m    #added by me
    Mac/[^.]*.mm   #added by me
    Mac/[^.]*.cmake
)

即使我手动添加文件,仍然会出现一系列编译错误。大约有20个错误,都与文件NSObjRuntime.h相关。
Parse Issue - Expected unqualified-id
Parse Issue - Unknown type name 'NSString'
Semantic Issue - Use of undeclared identifier 'NSString'
Parse Issue - Unknown type name 'NSString'
...
...
Semantic Issue - Use of undeclared identifier 'aSelectorName'
...
...
Semantic Issue - Use of undeclared identifier 'aClassName'
...

一段时间以来,类似的错误一直存在......根据我的阅读,这些错误是由于对Foundation Framework的依赖造成的,我相信我已经将其包含在项目中了。我还尝试在XCode中点击项目。现在我已经不知道该尝试什么了。人们说,在C/C++代码中使用Objective C并不难,但对XCode和Objective C都很新的我可能会导致困惑。对我来说,这只是第4天接触这个新平台。我需要做什么才能让XCode编译Objective C代码呢?请记住,我对此还有点陌生,所以我希望你能留下详细的答案,而不是常见于标签的模糊提示。我有点头疼,但如果你能帮我解决这个问题,我相信我就可以顺利完成后面的工作了。
更新:
我编辑了projects/MyPlugin/CMakeLists.txt文件,并在其中添加了.m和.mm规则。在运行prepmac.sh之后,这些文件被包含在项目中,但我仍然遇到相同的编译错误。
我将所有的.h文件和.mm文件从Obj C代码移动到了MyPlugin根目录,并重新运行了prepmac.sh文件。问题仍然存在。仍然是相同的编译错误。
1个回答

2
您的问题在于,您有一些.h文件被包含在具有Objective-C类型和/或包含的C++文件中。为了实现您想要的功能,所有用于c++的类都需要将所有obj c相关内容保留在#ifdef中,或者在头文件中根本不公开任何obj c内容。
例如,您可以在头文件中使用以下#ifdef:
#ifdef __OBJC__
     // Objective C / C++ code here
#endif

重要的是要记住,.h文件不仅是头文件,也是包含文件,因此它们实际上被包含了。如果你在.cpp文件中包含Objective C代码,编译器会感到困惑并报错。
编辑:最重要的是要确保任何Objective C头文件(或其他包含Objective C代码的文件)不会从cpp文件中包含。如果你能做到这一点,那么就没问题了。

那么,如果我包含开源的Objective C代码,那么我需要编辑每个头文件吗?我读到了一些关于使用Prefix.pch文件来避免这种情况的内容,甚至在一个Objective C项目示例中看到了一个,但我还没有弄清楚如何将其包含在FireBreath项目中。+1,这肯定会让我走上正确的轨道!感谢您抽出时间来解决这个问题!而且你是对的!CMake很烦人,但我可以看出它是必要的... :) - jamesmortensen
如果您要包含开源的Objective C代码,那么请不要在头文件中包含它的头文件,因为这些头文件也会被C++文件所包含。或者,您可以将#import语句包装在#ifdef语句中,以防止它被包含在cpp文件中。 - taxilian
好的,我觉得现在开始有点明白了。我把 Mac 留在了办公室,所以我会在周一试一下。再次感谢! :) - jamesmortensen
我最终采用了这里描述的PIMPL方法:https://dev59.com/FXNA5IYBdhLWcg3wL6sc#1061576,该方法通过创建一个C++包装器头文件来有效地防止将Objective C头文件包含在CPP文件中,该头文件充当Objective C++实现文件(.mm)和实际(.cpp)文件之间的层。 - jamesmortensen
这正是我想要解释的内容 =] - taxilian
是的!我看到了,直到阅读你在这里的回答之前我才理解其他帖子,所以+1和选中! :) 我想区别是我不需要使用 ifdef 头文件来使用包装器。我仍然不完全确定自己在做什么,可能本周晚些时候我会加入 IRC 并询问一些 CMake 的问题。现在我需要尝试在 Mac OS 状态栏中放置一个图标,看起来需要进行一些配置才能编译 XIB 文件。再次感谢你的帮助! :) - jamesmortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接