2010-09-21 46 views
0

所以,我一直在努力连接散列一个简单的应用程序,包括C++和Objective-C,来证明一些概念并尝试学习一些东西。混合C++和Objective-C(怀疑Automake问题)

下面是我在哪里,现在,我命令(正在运行,并重新运行上的变化)是

$ 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: 
+0

您是否尝试使用'.mm'扩展名重命名'.cpp'文件? – 2010-09-21 20:11:43

+0

是的,如果我这样做,那么automake没有找到任何输入文件,但是当我在'./src/Makefile.am'中注释掉'greetings_CFLAGS = -framework -Xlinker Foundation'这行时,所有的错误都变成了' /usr/include/c++/4.2.1/bits/istream.tcc:406:错误:C链接模板“ – 2010-09-21 20:17:27

+0

您可以将'Makefile'或'Makefile.in'添加到您的要点吗?我想知道是否缺少'.mm - > $(OBJEXT)'的后缀规则,这就是为什么没有输入文件的原因。 – 2010-09-22 06:16:41

回答

0

从zip文件打转转,这里是我建议:

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

#ifdef __cplusplus 
extern "C" 
#endif 

伎俩,以确保C++编译器会生成C函数和Objective-C的编译器可以处理的头。这将使Objective-C代码可以调用你的接口。

设置你的源代码树,你以前有:在src/共同的代码,特定于操作系统的代码src/darwinsrc/msdos(:P),src/win32等。列出EXTRA_foo_SOURCES中的所有来源,地址为Makefile.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符号,但没有提供。

0

你的问题“C链接模板”是由于extern "C"块内的#include <iostream>。尝试是这样的:

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

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

这将使greet()有C键,无头越来越误解。

+0

谢谢,这使得更多的意义,当我这样做时 - 问题是它回到没有找到问候()符号? – 2010-09-22 09:19:59