I have a cpp code in which I want to call a c function.
Both compile well to .o files, but when the clang++ is executing for compilation, I receive the following error:
file.cpp:74:12: error: expected unqualified-id
extern "C"
^
The code in the cpp file is the following:
void parseExtern(QString str)
{
#ifdef __cplusplus
extern "C"
{
#endif
function_in_C(str);
#ifdef __cplusplus
}
#endif
}
How can I avoid the error ? I can't compile the c file with clang++, I really need to use extern. Thanks.
The extern "C" linkage specification is something you attach to a function declaration. You don't put it at the call site.
In your case, you'd put the following in a header file:
#ifdef __cplusplus
extern "C"
{
#endif
void function_in_C(char const *); /* insert correct prototype */
/* add other C function prototypes here if needed */
#ifdef __cplusplus
}
#endif
Then in your C++ code, you just call it like any other function. No extra decoration required.
char const * data = ...;
function_in_C(data);
Related
#ifndef MAINCPP_H
#define MAINCPP_H
extern "C"
{ void displaylistfun(void);
void strfun(void);
}
#endif
Don't know why i am getting this error, I am trying to call Cpp function in .c file
extern "C" { ... } is a C++-specific thing, when you include the header file in a C source file you should be getting errors.
You need to use conditional compilation to have a header file that can be included in both C and C++ source files:
#ifndef MAINCPP_H
#define MAINCPP_H
#ifdef __cplusplus
// Only in C++
extern "C" {
#endif
void displaylistfun(void);
void strfun(void);
#ifdef __cplusplus
}
#endif
#endif // MAINCPP_H
Remember to include this header file on both the C++ and the C source files (so the C++ compiler knows that the functions are extern "C").
I have a .cpp file which I declare a function
#ifndef MyFile_hpp
#define MyFile_hpp
#ifdef __cplusplus
extern "C" {
#endif
void runCode();
#ifdef __cplusplus
}
#endif
#endif
This works fine. I can call this function within my Objc. In my implementation I have an extern void that it will not let me call. It's giving the undefined symbols. I need this to build as is, the extern will be declared in a different file upon compiling. Having the extern, should this compiler just trust me and let me build?
#include "MyFile.h"
extern int runMe();
#ifdef __cplusplus
extern "C" {
#endif
void runCode() {
runMe();
}
#ifdef __cplusplus
}
#endif
I think what you are doing is probably correct.
The compiler doesn't just trust you. A C++ function is declared to the linker using additional characters, or "decorations" that define the full detail of the cclass it is a member of and all its arguments. A C function has none of that, just the raw name, so it is easy for the linker to tell the difference.
I'm running into a mysterious situation with the GCC compiler. So I've got the following files:
//main.cpp
#include "mleak_cpp.h"
int main(int argc, char* argv[])
{
foo();
__memory_malloc(10,"hello",5);
return 0;
}
//mleak_cpp.h
......
void foo(void);
void* __memory_malloc(size_t size, const char* file, int line);
//mleak_cpp.cpp
//definitions of the functions;
void foo(void){printf("foo\n");
void* __memory_malloc(size_t size, const char* file, int line){
printf("%s,%d\n",file,line);
InitDoubleLinkList();
void* p = malloc(size);
if(p == NULL)
return NULL;
__DuLinkList* pListNode;
pListNode = (__DuLinkList*)malloc(sizeof(__DuLinkList));
pListNode->address = p;
pListNode->memorysize = size;
pListNode->file = file;
pListNode->line = line;
InsertBlockToList(pListNode);
return p;
}
For some reason, the call to void foo(void) is fine, but the call to "__memory_malloc" goes down with a linker error, "undefined reference" blah blah. What's the difference between the two functions that causes the different behaviour?
I tried adding "extern C" to the "#include" directive, so main.cpp reads:
extern "C"{
#include "mleak_cpp.h"
}
and adding the keyword "extern" before the declarations of the functions, and this time the call to "foo()" fails too with the same error.
I appreciate any help from you guys
You're placing extern "C" in the wrong place.
If main.c is truly a C file, and mleak_cpp.cpp is truly a C++ function, then you need to put an extern "C" ahead of the definition of __memory_malloc() like so:
extern "C" void* __memory_malloc(size_t size, const char* file, int line){
// ...
}
If you put extern "C" in the mleak_cpp.h file, it needs to be guarded:
#ifdef __cplusplus
extern "C" {
#endif
/* ... body of header ... */
#ifdef __cplusplus
}
#endif
Also, it's not clear why foo works in your example above, when one file calls __foo() but the other file defines foo(). I assume something more is at play, such as an editing error in your question.
extern "C" is for C++, not C, and tells it that the function's name shouldn't be mangled. In C code, you should never see this. Generally, you put it in header files, and you guard it, like this:
#ifdef __cplusplus
extern "C" {
#endif
/* C and C++ compatible header file body here */
#ifdef __cplusplus
} /* end extern "C" */
#endif
If you do it this way though, you need to include the header file in both your C and C++ files, so that the C++ compiler knows to use C linkage.
You can put the extern "C" in front of the function definition in C++ instead and leave it out of the header, but this only works if you only include the headers in C code, so it's recommended to do it the way I pointed out above.
I need to call a C++ member function from a C program.
I created .cpp/.h wrapper files in the C code, wrapping the C++ member functions.
i.e.- wrapper.cpp
#include "wrapper.h"
extern "C" {
void wrap_member1()
{
Class::member1();
}
void wrap_member2()
{
Class::member2();
}
}
and wrapper.h:
#include <windows.h>
#include <stdio.h>
#include "../C++ class with members I need to call.h"
extern "C" void wrap_member1();
extern "C" void wrap_member2();
My problem is when I complie:
error C2061: syntax error : identifier 'Class'
It points to the .h declaration of the C++ class as an error. Same result as if I did not have the wrapper files....?
P.S. I also removed the "extern "C" " from the prototypes and received an error on the wrapper function:
error C2732: linkage specification contradicts earlier specification for 'wrap_member1'
Any advice?
There are two issues:
One, you are including a C++ header file in a C header file. This means the C compiler gets C++ code. This is what causes the error you are experiencing. As Reed Copsey suggests, put the #include in the C++ source file instead of the C header file.
Two, you are using extern "C" in the C header file. Wrap your statement in an #ifdef as such:
#ifdef __cplusplus
extern "C" {
#endif
/* Functions to export to C namespace */
#ifdef __cplusplus
}
#endif
This will allow the file to be usable for both C and C++.
In your wrapper you must conditionaly compile the extern "C" part, because is a C++ only construct:
wrapper.h:
#ifdef __cplusplus
extern "C" {
#endif
extern void wrap_member1();
#ifdef __cplusplus
}
#endif
In the wrapper.cpp:
extern "C" void wrap_member1()
{
Class::Member1();
}
In your C module you include only wrapper.h and link to wrapper.obj.
BTW Objective-C is capable of consuming C++, just change the name of your file from *.m to *.mm in XCode.
You need to include your class in wrapper.cpp:
#include "wrapper.h"
#include "ClassHeaderFile.h" // The header that defines "Class"
extern "C" {
void wrap_member1()
{
Class::member1();
}
void wrap_member2()
{
Class::member2();
}
}
I just got some C code that uses extern "C" to declare external functions like this:
extern "C" void func();
Is this valid C? I'm getting an error at this line, but I'm not sure if it's because of this or something else.
No, it's not valid C. It should only be used in C++ code to refer to functions defined in C code. The extern "C" should be surrounded in a ifdef __cplusplus/#endif block:
// For one function
#ifdef __cplusplus
extern "C"
#endif
void func();
// For more than one function
#ifdef __cplusplus
extern "C"
{
#endif
void func1();
void func2();
#ifdef __cplusplus
}
#endif
this is a C++ notation to tell the compiler/linker to use C calling standards.
Usually that line is wrapped in an pre-processor statement.
#ifdef __cplusplus
extern "C" {
#endif
// stuff
#ifdef __cplusplus
}
#endif
Not valid in C. If present after preprocessing this will result in a diagnostic as per the standard.
For C++, this turns of name-mangling. See this for more details as to why it may be required. Can you post some more details?