【问题标题】:Mixing C and C++ code with userdefined "typename()" function in C在 C 中将 C 和 C++ 代码与用户定义的“typename()”函数混合
【发布时间】:2014-03-03 05:58:17
【问题描述】:

我正在尝试编写一个调用 C 函数的 C++ 代码,比如说hello_world() 进而调用用户定义的typename() 函数。当我在 C++ 中包含我的 C 代码时,会出现编译错误,我知道 typename 是 C++ 中的一个关键字,但是为了包含 C 代码,我正在使用

extern "C" { #include "hello_world.h"}

在我的 C++ 代码中,编译过程中仍然存在错误,任何避免这种情况并编译代码的建议,我将不胜感激。

我无法将用户定义的typename() 函数的名称更改为其他名称。那怎么办呢……?

这样的错误: In file included from New_test.cpp:19:0: ../tools/symbol.h:38:14: error: expected unqualified-id before ‘typename’ ../tools/symbol.h:38:14: error: expected initializer before ‘typename’ In file included from New_test.cpp:604:0: /usr/include/i386-linux-gnu/sys/poll.h: In function ‘int readpacket(channel*, void*, size_t)’: /usr/include/i386-linux-gnu/sys/poll.h:48:1: error: expected unqualified-id before string constant New_test.cpp:612:52: error: ‘poll’ was not declared in this scope

【问题讨论】:

  • 很可能,您可以对标头进行分区,以便 typename() 仅在调用它的 C 源中声明。最小化 C++ 源代码中包含的标头。如果您需要能够从 C++ 调用 typename(),请考虑更改您的设计以接受函数指针。
  • 如何限制 typename() 只能在 C 源代码中声明。使用 "extern "C" { #include "some_c.h"}" 不会这样做...?
  • 只有 c... 但我调用了一个调用 typename() 的 C 函数...
  • Trilok,请分享更多信息——赏金描述听起来好像一个或多个答案是足够的,但您需要更多“来自可靠和/或官方来源的证据”。正如目前所描述的问题,我认为我的回答就足够了。如果你有 SSCCE 会有所帮助。
  • @TrilokM,请说明您遇到了什么错误。

标签: c++ c mixing


【解决方案1】:

你的头文件中可能需要这样的东西:

文件:common_header.h

#ifdef __cplusplus
extern "C" {
#endif

extern void newname_typename();

#ifdef __cplusplus
}
#endif

然后是一个纯 C 编译单元:

#include "common_header.h"
#include "hello_world.h"
void newname_typename() {
   typename();
}

在 C++ 中:

#include "common_header.h"

void do_stuff() {
  newname_typename();
}

并且您需要确保您的 Makefile 最终执行以下操作:

gcc c_only_code.c -o something1.o
g++ cplus_only_code.cxx -o something2.o
gcc something1.o something2.o <other stuff> -o binary  

【讨论】:

  • 我应该使用 gcc cplus_only_code.c -o something2.o 还是 g++ cplus_only_code.cpp -o something2.o...?
  • -o 二进制有什么用...?是强制的吗?
  • 抱歉,修正了我的错字。但这只是一个例子,它取决于你的构建系统。此外(二进制)只是可执行文件的一个示例。我只是想强调,您需要确保 C 代码由 C 编译器编译,而 C++ 由 C++ 编译器编译
  • 为了使用 "extern "C"{ #include "some.h" }" 我需要创建 some.h 的共享库吗?
  • 因为我尝试使用 extern "C" { #include "some.h"} 其中我的 some.h 定义了所有 c 函数并且我的 cpp 代码仍然不可编译
【解决方案2】:

您可以通过以下方式对事物进行分区,以使其能够正确编译和链接。 C++源文件不需要知道有一个函数叫typename()

文件'some_c.c':

#include "some_c.h"

void typename(); /* This declaration will suffice. */

void hello_world()
{
    typename();
}

文件'some_c.h'

/* References to typename()'s declaration must be deleted from this
** header file.  If it turns out that there are some other parts of the
** header file which somehow depend on the typename() declaration, you
** must separate this into multiple header files. 
*/
void hello_world();

文件'some_cpp.cpp':

/* Arguably this should show up in some_c.h, protected by
** #ifdef __cplusplus barriers.  But this should work too:
*/
extern "C" {
#include "some_c.h"
}

void SomeClass::someMethod()
{
    hello_world();
}

【讨论】:

  • /* 必须从这个 ** 头文件中删除对 typename() 声明的引用。如果事实证明**头文件的某些其他部分以某种方式依赖于 typename() 声明,则**必须将其分成多个头文件。 */ 所以我应该在哪里声明 typename();
  • 您必须在some_c.csome_cpp.cpp 未包含的其他地方声明typename()
  • 为了使用 "extern "C"{ #include "some.h" }" 我需要创建 some.h 的共享库吗?
  • 因为我尝试使用 extern "C" { #include "some.h"} 我的 some.h 定义了所有 c 函数,而我的 cpp 代码仍然不可编译。
  • 不,您不需要一个库,无论是共享的还是其他的。 “仍然无法编译”——好的,为什么会失败?
【解决方案3】:

extern "C" 没有告诉 c++ 编译器用 C 编译,但它告诉使用 C 类型链接。 与 C++ 不兼容的代码仍然会产生错误。您只能在 C 代码中使用“坏”的 C 头文件。创建一个新的 C 头文件,该文件公开所需的函数/代码(通过包装/重命名与 C++ 兼容)并在 C++ 代码中和外部“C”中使用该新文件 C Header。

【讨论】:

    【解决方案4】:

    这个问题不太可能有官方答案。原因是extern "C"指令有一个官方的用法和意图,所有的权威文档都会讨论这个用法和意图。您正在尝试将 extern "C" 用于不适合的用途。很难找到讨论所有意外用例的官方文档。我认为这样的文件将无限长。

    extern "C" 的目的是允许 C 函数调用 C++ 函数,反之亦然。问题的出现是因为默认情况下 C++ 在目标文件中使用与 C 不同的命名约定。 C++ 使用重整的函数名,C 使用直接的函数名。此外,C++ 可以将变量传递给与 C 不同的函数。为了允许 C++ 调用 C 函数(反之亦然),extern "C" 通知编译器它需要使用 C 函数调用约定。

    http://en.wikipedia.org/wiki/Extern_%22C%22#Linking_C_and_C.2B.2B_code

    因此给出以下要求

    1) a function named `typename` exists in a C source file
    2) the function cannot be renamed
    3) the function must be callable from a C++ source file
    

    唯一的解决方案是创建一个桥接文件,如 Andrew McDonnell 的帖子中所述。

    【讨论】:

      【解决方案5】:

      这适用于任何有同样问题的人:为了调用函数名称与 C++ 中定义的关键字相同的 C 函数,请使用 extern "C" { /*function declaration */} 并且您还需要有一个共享库。

      谢谢大家...!!!

      【讨论】:

        猜你喜欢
        • 2021-09-20
        • 2016-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        • 2013-02-07
        相关资源
        最近更新 更多