在 C 源文件中包含带有命名空间的 C++ 头文件会导致编译错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16058245/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Including C++ header file with namespace in C source file causes compilation error
提问by rajeshk
I'm not an expert C++ programmer, and i have been recently doing a trick thing in C++ which is causing me the below issue.
我不是专业的 C++ 程序员,最近我一直在用 C++ 做一个技巧,这导致了我出现以下问题。
Objective of my task: Specific non system thread (cooperative threading actually) safe module is duplicated to create a system thread safe version to support different needs in the system. But instead of creating sys_XXX functions to keep the compatibility, we have decided to create a namespace to protect the system thread version in a C++ header file. I can actually include this in the CPP file and work happily but i just realised my funcInit call is not called before it reaches the CPP file control. Unfortunately this init for the cooperative threading version is in a C file. Now i need to init my system thread safe version from the same place, but im have been blocked by the compilation error which are hard to solve from my knowledge.
我的任务目标:复制特定的非系统线程(实际上是协作线程)安全模块以创建系统线程安全版本,以支持系统中的不同需求。但是我们并没有创建 sys_XXX 函数来保持兼容性,而是决定在 C++ 头文件中创建一个命名空间来保护系统线程版本。我实际上可以将它包含在 CPP 文件中并愉快地工作,但我刚刚意识到我的 funcInit 调用在到达 CPP 文件控件之前没有被调用。不幸的是,协作线程版本的 init 位于 C 文件中。现在我需要从同一个地方初始化我的系统线程安全版本,但是我被编译错误阻止了,根据我的知识很难解决。
Compilation Error log:-
编译错误日志:-
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
Source and header snippets FYI :-
源代码和标题片段仅供参考:-
C header file (unicode.h):
C 头文件(unicode.h):
// all functions called from the C source file
funcInit();
funcA();
funcB();
funcTerm();
C header file (unicode.c):
C 头文件 (unicode.c):
// all functions called from the C source file
funcInit() {
}
funcA() {
}
funcB() {
}
funcTerm() {
}
C++ header file (sys_unicode.h):
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++ source definition (sys_unicode.cpp):
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 source # 1 (utils.cpp):
CPP 源#1 (utils.cpp):
#include "sys_unicode.h"
using namespace SystemThreadUtils;
utils::utils_init()
{
funcA();
funcB();
}
C source #2 (sysinit.c):
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
}
回答by Arne Mertz
You cannot use namespaces in C, extern "C"
also is not allowed in C. So what could be a solution: Your C++ module defines a set of functions in namespace SystemThreadUtils
that need to get called in C-Code. Since you cannot do that directly, you will have to write a C-conformant wrapper around them:
您不能在 C 中使用命名空间,在 C 中extern "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();
}
}
Meaning: you need a header that is valid C code and declares a delegating function for each C++ function you need to call from C. The source is in C++ and just does the call.
含义:您需要一个是有效 C 代码的标头,并为您需要从 C 调用的每个 C++ 函数声明一个委托函数。源代码在 C++ 中并且只执行调用。
See Calling C++ functions from C fileas well.
另请参阅从 C 文件调用 C++ 函数。