混合C ++和Objective-C(可疑的Automake问题)

时间:2010-09-21 19:49:04

标签: c++ objective-c gcc automake

所以,我已经工作了一段时间来连接一个简单的应用程序,包括C ++和Objective-C,来证明一些概念并尝试学习一些东西。

这是我现在所处的位置,我的命令(正在运行,并在更改时重新运行)

$ autoreconf -vis && make clean && ./configure && make && ./src/greetings

请注意,我希望它在我完成后会运行,这是一个简短的文件列表:

$ find . | ack '\.(?:cpp|mm|h)$'
./src/darwin/greet.cpp
./src/darwin/greeting.h
./src/darwin/greeting.mm
./src/greet.h
./src/main.cpp
./src/mingw32/greet.cpp
./src/mingw32/greet.h

完整的文件都可以在此Gist at Github中找到。

而不是专门用于混合语言的问题(我甚至没有做到那么远) - 我似乎偶然发现编译器没有意识到这是Objective-C(或ObjecC++) - 因此,我的autoconf文件位于this gist

使用完整的错误输出here, also in a Gist

以下是一个示例:

In file included from /usr/include/c++/4.2.1/iosfwd:48,
                 from /usr/include/c++/4.2.1/ios:43,
                 from /usr/include/c++/4.2.1/ostream:45,
                 from /usr/include/c++/4.2.1/iostream:45,
                 from darwin/greet.cpp:10:
/usr/include/c++/4.2.1/bits/stringfwd.h:48: error: template with C linkage
/usr/include/c++/4.2.1/bits/stringfwd.h:51: error: template with C linkage
/usr/include/c++/4.2.1/bits/stringfwd.h:54: error: template with C linkage
/usr/include/c++/4.2.1/bits/stringfwd.h:58: error: template specialization with C linkage
/usr/include/c++/4.2.1/bits/stringfwd.h:63: error: template specialization with C linkage
In file included from /usr/include/c++/4.2.1/iosfwd:49,
                 from /usr/include/c++/4.2.1/ios:43,
                 from /usr/include/c++/4.2.1/ostream:45,
                 from /usr/include/c++/4.2.1/iostream:45,
                 from darwin/greet.cpp:10:

2 个答案:

答案 0 :(得分:0)

您的“具有C链接的模板”问题归因于#include <iostream>块内的extern "C"。尝试这样的事情:

#include <CoreFoundation/CoreFoundation.h>
#include <iostream>

/* In a #ifdef __cplusplus block, if you want. */
extern "C"
void greet() {
  /* ... */
}

这将使greet()具有C链接,而不会错误解释标题。

答案 1 :(得分:0)

从使用zip文件开始,我推荐以下内容:

在语言边界使用仅C接口。这将避免automake不存在的Objective-C ++支持。使用

#ifdef __cplusplus
extern "C"
#endif
对标头进行操作以确保C ++编译器将生成C函数,而Objective-C编译器可以处理标头。这将使Objective-C代码可以调用您的界面。

按照以前的方式设置源代码树:src/中的公共代码,src/darwin中的操作系统特定代码,src/msdos(:P),src/win32等等上。列出EXTRA_foo_SOURCESMakefile.am的所有来源。

configure.ac中,测试您正在编译的平台,并使用AM_CONDITIONAL设置Makefile.am可以读取的标记(您已经正确地完成了此操作)。

Makefile.am中,使用条件语包含正确的其他来源:

if OS_DARWIN
  foo_SOURCES += darwin/foo.m darwin/bar.h darwin/baz.m
  foo_LDFLAGS = -Wl,-framework,Foundation
endif

请注意,由于how the linker is chosen,将尝试使用C ++链接。用于生成Objective-C代码链接的其他链接器标志需要位于foo_LDFLAGS

您的案例中发生了以下情况:在greet.h中,您未将void greet();声明为extern "C"。这意味着当编译main.cpp时,它期望void greet()具有C ++链接(在我的例子中,符号为greet)。编译darwin/greet.cpp并将void greet()声明为extern "C",因此它生成了C版本(符号为_greet)。链接然后失败,因为链接器期望greet符号,但没有提供。