【问题标题】:Mixing C++ and Objective-C (Suspected Automake problem)混合 C++ 和 Objective-C(怀疑 Automake 问题)
【发布时间】:2010-09-26 12:58:06
【问题描述】:

所以,我一直致力于连接散列一个简单的应用程序,包括 C++ 和 Objective-C,以证明一些概念并尝试学习一些东西。

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

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

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

$查找。 | 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++)-出于这个原因,我的自动配置文件在this gist

带有完整的错误输出here, also in a Gist

这是一个示例:

在 /usr/include/c++/4.2.1/iosfwd:48 包含的文件中, 来自/usr/include/c++/4.2.1/ios:43, 来自 /usr/include/c++/4.2.1/ostream:45, 来自/usr/include/c++/4.2.1/iostream:45, 来自达尔文/greet.cpp:10: /usr/include/c++/4.2.1/bits/stringfwd.h:48:错误:带有 C 链接的模板 /usr/include/c++/4.2.1/bits/stringfwd.h:51:错误:带有 C 链接的模板 /usr/include/c++/4.2.1/bits/stringfwd.h:54:错误:带有 C 链接的模板 /usr/include/c++/4.2.1/bits/stringfwd.h:58:错误:带有 C 链接的模板特化 /usr/include/c++/4.2.1/bits/stringfwd.h:63:错误:带有 C 链接的模板特化 在 /usr/include/c++/4.2.1/iosfwd:49 包含的文件中, 来自/usr/include/c++/4.2.1/ios:43, 来自 /usr/include/c++/4.2.1/ostream:45, 来自/usr/include/c++/4.2.1/iostream:45, 来自达尔文/greet.cpp:10:

【问题讨论】:

  • 您是否尝试过使用 .mm 扩展名重命名 .cpp 文件?
  • 是的,如果我这样做了,那么 automake 找不到输入文件,但是当我在 ./src/Makefile.am 中注释掉 greetings_CFLAGS = -framework -Xlinker Foundation 行时,错误都会变成 /usr/include/c++/4.2.1/bits/istream.tcc:406: error: template with C linkage 之类的东西
  • 你能把 MakefileMakefile.in 添加到你的 gist 中吗?我想知道是否可能缺少.mm -> $(OBJEXT) 的后缀规则,这就是没有输入文件内容的原因。
  • 你能上传一个make dist 让我修改吗?

标签: c++ objective-c gcc automake


【解决方案1】:

通过使用 zip 文件,我推荐以下内容:

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

#ifdef __cplusplus
extern "C"
#endif

对你的头文件进行技巧以确保 C++ 编译器将生成 C 函数并且 Objective-C 编译器可以处理头文件。这将使 Objective-C 代码可以调用您的接口。

像以前一样设置源代码树:src/ 中的公共代码,src/darwinsrc/msdos (:P)、src/win32 中的操作系统特定代码等。在Makefile.am 中列出EXTRA_foo_SOURCES 中的所有来源。

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 被编译时,它需要一个具有C++ 链接的void greet()(在我的例子中,符号是greet)。 darwin/greet.cpp 已编译并将 void greet() 声明为 extern "C",因此它生成了 C 版本(带有符号 _greet)。然后链接失败,因为链接器需要一个 greet 符号,但没有提供该符号。

【讨论】:

    【解决方案2】:

    您的“带有 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 链接,而标题不会被误解。

    【讨论】:

    • 谢谢,这更有意义,但当我这样做时 - 问题是它回到了找不到 greet() 符号?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多