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

Вы пытались переименовать файлы '.cpp' с расширением' .mm'? –

+0

Да, если я это сделаю, то автомат не найдет входных файлов, однако, когда я прокомментирую строку 'greetings_CFLAGS = -framework -Xlinker Foundation' в'./Src/Makefile.am', тогда ошибки все будут меняться на что-то вроде ' /usr/include/c++/4.2.1/bits/istream.tcc:406: ошибка: шаблон с C linkage' –

+0

Можете ли вы добавить 'Makefile' или' Makefile.in' в свой смысл? Мне интересно, возможно ли, что существует правило суффикса для '.mm -> $ (OBJEXT)', и поэтому нет файлов ввода. –

ответ

0

От игры вокруг с архивом, вот что я рекомендую:

Используйте C-только интерфейс на границе языка. Это позволит избежать несуществующей поддержки Objective-C++ от automake. Используйте

#ifdef __cplusplus 
extern "C" 
#endif 

трюк на заголовки, чтобы убедиться, что C++ компилятор будет генерировать функции C и Objective-C компилятор может обрабатывать заголовки. Это позволит коду Objective-C вызвать ваш интерфейс.

Настройка исходного дерева, как у вас есть перед: общий код в src/, OS-зависимый код в src/darwin, src/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", поэтому он выпустил версию С (с символом _greet). Связывание тогда не получилось, потому что компоновщик ожидал символ greet, но ничего не предоставил.

0

Ваш «шаблон с рычажной С» проблема связана с #include <iostream> внутри extern "C" блока. Попробуйте что-то вроде этого:

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

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

Это позволит greet() иметь C связи, без заголовков получать неверно истолкованы.

+0

Спасибо, это имеет больший смысл, когда я это делаю - проблема в том, что он возвращается к тому, чтобы не найти символ greet()? –