【问题标题】:Including C++ header file with namespace in C source file causes compilation error在 C 源文件中包含具有命名空间的 C++ 头文件会导致编译错误
【发布时间】:2013-04-10 02:37:37
【问题描述】:

我不是专业的 C++ 程序员,最近我在 C++ 中做了一个诡计,导致我出现以下问题。

我的任务目标:复制特定的非系统线程(实际上是协作线程)安全模块以创建系统线程安全版本以支持系统中的不同需求。但是我们决定创建一个命名空间来保护 C++ 头文件中的系统线程版本,而不是创建 sys_XXX 函数来保持兼容性。我实际上可以将它包含在 CPP 文件中并愉快地工作,但我刚刚意识到我的 funcInit 调用在它到达 CPP 文件控件之前没有被调用。不幸的是,协作线程版本的这个 init 在 C 文件中。现在我需要从同一个地方初始化我的系统线程安全版本,但是我被编译错误阻止了,据我所知很难解决。

编译错误日志:-

In file included from sysinit.c:87:
sys_unicode.h:39: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'SystemThreadUtils' <== corresponds to line [namespace SystemThreadUtils {]
sysinit.c:88:
sysinit.c:512: error: expected identifier or '(' before string constant <== corresponds to line [extern "C" bool SystemThreadUtils::funcInit(void);]
sysinit.c:513: error: expected identifier or '(' before string constant <== corresponds to line [extern "C" bool SystemThreadUtils::funcTerm(void);]
sysinit.c: In function 'SysInit':
sysinit.c:817: error: 'SystemThreadUtils' undeclared (first use in this function) <= corresponds to line [SystemThreadUtils::funcInit();]
sysinit.c:817: error: (Each undeclared identifier is reported only once
sysinit.c:817: error: for each function it appears in.)
sysinit.c:817: error: expected ')' before ':' token
sysinit.c: In function 'SysTerm':
sysinit.c:2737: error: expected expression before ':' token <== corresponds to line [SystemThreadUtils::funcTerm();]
sysinit.c:2737: warning: label 'SystemThreadUtils' defined but not used

来源和标题 sn-ps 仅供参考:-

C 头文件(unicode.h):

// all functions called from the C source file
funcInit();
funcA();
funcB();
funcTerm();

C 头文件(unicode.c):

// all functions called from the C source file
funcInit() {
}
funcA() {
}
funcB() {
}
funcTerm() {
}

C++ 头文件(sys_unicode.h):

#include "unicode.h"
namespace SystemThreadUtils {

    // below functions called from the C source file
    extern "C" funcInit();
    extern "C" funcTerm();

    // below functions called from the CPP source file
    funcA();
    funcB();
}

C++ 源代码定义(sys_unicode.cpp):

#include "sys_unicode.h"

namespace SystemThreadUtils {

    // below functions are called from C source
    funcInit() {
    }
    funcTerm() {
    }

    // below methods are called from CPP source
    funcA() {
    }
    funcB() {
    }
}

CPP 源 #1 (utils.cpp):

#include "sys_unicode.h"

using namespace SystemThreadUtils;

utils::utils_init()
{
   funcA();
   funcB();
}

C 源代码 #2 (sysinit.c):

#include "sys_unicode.h"

extern "C" bool SystemThreadUtils::funcInit(void);
extern "C" bool SystemThreadUtils::funcTerm(void);

SysInit ()
{
   funcInit(); // non system thread safe version
   SystemThreadUtils::funcInit();  // system thread safe version
}
SysTerm ()
{
   funcTerm(); // non system thread safe version
   SystemThreadUtils::funcTerm();  // system thread safe version
}

【问题讨论】:

  • @Najzero 感谢 SO 链接,但这并不能解决我的问题。我在 CPP 头文件中有命名空间,我需要使用它来避免与同名的 C 函数混淆。 unicode.c 和 unicode.cpp 都包含 x 个同名函数。
  • sys_unicode.h:39。我看不到第 39 行,是整个文件吗?
  • @LefterisE: 是的,它不是一个完整的文件,但是如果你看到这个(

标签: c++ c compilation header namespaces


【解决方案1】:

您不能在 C 中使用命名空间,extern "C" 在 C 中也是不允许的。所以可能的解决方案是:您的 C++ 模块在命名空间 SystemThreadUtils 中定义了一组需要在 C 代码中调用的函数。由于您不能直接执行此操作,因此您必须围绕它们编写符合 C 的包装器:

//C/C++ - header "sys_unicode_for_c.h"

#ifdef __cplusplus
extern "C" {
#endif

  void STU_funcInit();
  void STU_funcTerm();

#ifdef __cplusplus
} //end extern "C"
#endif

//C++-source: sys_unicode_for_c.hpp
#include "sys_unicode.h"

extern "C" {
  void STU_funcInit() {
    SystemThreadUtils::funcInit();
  }
  void STU_funcTerm() {
    SystemThreadUtils::funcTerm();
  }
}

含义:您需要一个有效 C 代码的标头,并为您需要从 C 调用的每个 C++ 函数声明一个委托函数。源代码是 C++ 并且只是进行调用。

也请参阅Calling C++ functions from C file

【讨论】:

    猜你喜欢
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多