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.
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.
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):
// all functions called from the C source file
funcInit();
funcA();
funcB();
funcTerm();
C header file (unicode.c):
// all functions called from the C source file
funcInit() {
}
funcA() {
}
funcB() {
}
funcTerm() {
}
C++ header file (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):
#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):
#include "sys_unicode.h"
using namespace SystemThreadUtils;
utils::utils_init()
{
funcA();
funcB();
}
C source #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
}
cpp file (at file scope), or inside a class or function definition. In general, avoid putting using directives in header files (*. h) because any file that includes that header will bring everything in the namespace into scope, which can cause name hiding and name collision problems that are very difficult to debug.
Under no circumstances must you use namespace std within a header file, that's a recipe for errors straight away.
In C program should necessarily contain the header file which stands for standard input and output used to take input with the help of scanf() and printf() function respectively.
Since you can't put a namespace using statement at the top level of the header file, you must use a fully qualified name for Standard Library classes or objects in the header file. Thus, expect to see and write lots of std::string, std::cout, std::ostream, etc. in header files.
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++ - 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.
See Calling C++ functions from C file as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With