简体   繁体   English

在C源文件中包含带有命名空间的C ++头文件会导致编译错误

[英]Including C++ header file with namespace in C source file causes compilation error

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. 但是,我们决定创建一个命名空间来保护C ++头文件中的系统线程版本,而不是创建sys_XXX函数以保持兼容性。 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. 我实际上可以将它包含在CPP文件中并愉快地工作但我刚刚意识到我的funcInit调用在它到达CPP文件控件之前没有被调用。 Unfortunately this init for the cooperative threading version is in a C file. 不幸的是,协作线程版本的这个init在C文件中。 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. 现在我需要从同一个地方初始化我的系统线程安全版本,但我已被编译错误阻止,这是我知道很难解决的。

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 :- 来源和标题摘要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
}

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. 你不能在C中使用命名空间,在C中也不允许使用extern "C" 。那么可能是一个解决方案:你的C ++模块在命名空间SystemThreadUtils中定义了一组需要在C-Code中调用的函数。 Since you cannot do that directly, you will have to write a C-conformant wrapper around them: 由于您不能直接执行此操作,因此必须围绕它们编写符合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 file as well. 另请参阅从C文件调用C ++函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM