2010-09-21 50 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