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();
}
}
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'm writing a C library, which may potentially be useful to people writing C++. It has a header which looks like this:
#ifndef FOO_H_
#define FOO_H_
#include <bar.h>
#include <stdarg.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void foo_func();
#ifdef __cplusplus
}
#endif
#endif
and I was wondering - should I move the extern "C" bit before including the header include directives? Especially seeing how, in practice, some of those headers might themselves have an extern "C"?
NO, in general you shouldn't move it to include the headers.
extern "C" is used to indicate that the functions is using the C calling convention. The declaration has no effect on variables and #defines, so there is no need to include these. If an #include is inside an extern "C" block, this effectively modifies the function declarations inside that header file!
Background: Without the extern "C" declaration, when compiling using a C compiler, a function is assumed to follow the C convention, and when compiling using a C++ compiler, the C++ convention is assumed. In case the same header file is used for C and C++ code, you would get a linker error, since the compiled function has different names in C and C++.
Although it's possible to put all your code between the #ifdef blocks, I personally don't like it, because it's really only intended for the function prototypes, and I frequently see people copy-pasting this at places where it shouldn't be. The cleanest way is to keep it where it's supposed to be, which is around the function prototypes in a C/C++ header file.
So, to answer your question "should I move the extern "C" bit before including the header include directives?", my answer is: No, you shouldn't.
But is it possible? Yes, and in many cases this won't break anything. Sometimes it is even necessary, if the function prototypes in an external header file are incorrect (e.g. when they are C functions and you want to call them from C++) and you cannot change that library.
However, there are also cases where doing so breaks the build. Here's a simple example that fails to compile if you wrap the include using extern "C":
foo.h:
#pragma once
// UNCOMMENTING THIS BREAKS THE BUILD!
//#ifdef __cplusplus
//extern "C" {
//#endif
#include "bar.h"
bar_status_t foo(void);
//#ifdef __cplusplus
//}
//#endif
foo.c:
#include <stdio.h>
#include "foo.h"
#include "bar.h"
bar_status_t foo(void)
{
printf("In foo. Calling bar wrapper.\n");
return bar_wrapper();
}
bar.h:
#pragma once
typedef enum {
BAR_OK,
BAR_GENERIC_ERROR,
BAR_OUT_OF_BEAR,
// ...
} bar_status_t;
extern "C" bar_status_t bar_wrapper(void);
bar_status_t bar(void);
bar.cpp:
#include <iostream>
#include "bar.h"
extern "C" bar_status_t bar_wrapper(void)
{
std::cout << "In C/C++ wrapper." << std::endl;
return bar();
}
bar_status_t bar(void)
{
std::cout << "In bar. One bear please." << std::endl;
return BAR_OK;
}
main.cpp:
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
#include "bar.h"
int main(void)
{
bar_status_t status1 = foo();
bar_status_t status2 = bar();
return (status1 != BAR_OK) || ((status2 != BAR_OK));
}
When uncommenting the blocks in a.h, I get the following error:
main2.cpp:(.text+0x18): undefined reference to `bar'
collect2.exe: error: ld returned 1 exit status
Makefile:7: recipe for target 'app2' failed
Without, it builds fine. A C main calling only C functions from foo and bar will build fine either way, since it's unaffected by the #ifdef __cplusplus blocks.
Surprisingly yes. After reading the standard now even I would write
#ifndef FOO_H_
#define FOO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <bar.h>
#include <stdarg.h>
#include <stddef.h>
void foo_func();
#ifdef __cplusplus
}
#endif
#endif
For 2 reasonss:
1 Having nested extern "C" are no problem, so your bar.h include would be fine. Like this it looks clearer and more important
2 To be really portable your surprisingly have to wrap an extern "C" around your C headers for C++ users, if they don't want to.
Because I just looked thru the C++ Standard and 16.5.2.3 Linkage [using.linkage] states
Whether a name from the C standard library declared with external linkage has extern
"C" or extern "C++" linkage is implementation-defined. It is
recommended that an implementation use extern "C++" linkage for this
purpose.1
To be safe than sorry, you indeed should wrap an extern "C" around those includes but, you should not have to, since this implies to the headers in D.9 C headers [depr.c.headers] like <stdlib.h> which you are using.
This is covered in the C++ FAQ.
First, How to include a standard C header file in C++ code? Nothing special is needed, as standard C header files work seamlessly with C++. So you don't need to wrap stdarg.h and stddef.h in extern "C".
Then, for non-standard C headers, there are two possibilities: either you can’t change the header, or you can change the header.
When you can't change the C header, wrap the #include in extern "C".
// This is C++ code
extern "C" {
// Get declaration for f(int i, char c, float x)
#include "my-C-code.h"
}
int main()
{
f(7, 'x', 3.14); // Note: nothing unusual in the call
// ...
}
When you can change the header, edit it to conditionally include extern "C" in the header itself:
#ifdef __cplusplus
extern "C" {
#endif
. . .
#ifdef __cplusplus
}
#endif
In your case it comes down to whether you have control over the contents of bar.h. If it's your header, then you should modify it to include extern "C" and not wrap the #include itself.
Headers should work the same way regardless of how/when/where they are included. Wrapping an #include in extern "C", #pragma pack, special #defines, etc, should be reserved for last resort workarounds, as this may interfere with how the header behaves in different scenarios, reducing the system's maintainability in the long run.
As StoryTeller said in the comments:
Some headers are explicitly written under the assumption that the outermost "scope" has C++ language linkage. They may use __cplusplus to remove template declarations, and if you wrap them up like you wish to, your header will be fundamentally broken. So as mentioned already, make your declarations correct, and let other headers do their thing unimpeded. Even standard library headers may break (since an implementer may reason its going to be shared anyway, and then do some expert friendly things inside).
Note that standard C headers may be implemented using C linkage, but may also be implemented using C++ linkage. In which case wrapping them in extern "C" might result in link errors.
I recently saw this block at the beginning of a .h file.
#ifdef __cplusplus
extern "C" {
#include <cstddef>
#include <cstdint>
#else
#include <stddef.h>
#include <stdint.h>
#endif /* __cplusplus */
Does wrapping a #include directive for a standard C++ header in extern "C" { ... actually do anything? Is it functionally different from:
#ifdef __cplusplus
#include <cstddef>
#include <cstdint>
extern "C" {
#else
#include <stddef.h>
#include <stdint.h>
#endif /* __cplusplus */
I was under the impression that this makes no difference, but I'm seeing it so often I am becoming curious.
Based on the "If ...def" statement in that header file, the
"if" block : "if you use the particular header file in C++"
"else" block : "if you use the particular header file not in C++, could be C"
if you do not wrap the headers in "extern C" in the "if" block(which is meant for C++), the "C" linkage wont be maintained for the function names.
"C" do not have function over loading concept, but where as C++. So C++ compiler does some function name mangling for "extern C" functions.
Here is a very nice article.
In C++ source, what is the effect of extern “C”? - in stack over flow.
For regular standard C libraries, the extern wrapper not required. Mostly it is taken care by standard C.
ex: something like below (yvals.h on windows).
#define _C_LIB_DECL extern "C" { /* C has extern "C" linkage */
#define _END_C_LIB_DECL }
#define _EXTERN_C extern "C" {
#define _END_EXTERN_C }
I am quite new to C and C++. But I have some C++ functions which I need to call them from C. I made an example of what I need to do
main.c:
#include "example.h"
#include <stdio.h>
int main(){
helloWorld();
return 0;
}
example.h:
#ifndef HEADER_FILE
#define HEADER_FILE
#ifdef __cplusplus
extern "C" {
#endif
void helloWorld();
#ifdef __cplusplus
}
#endif
#endif
example.cpp:
#include <iostream.h>
void helloWorld(){
printf("hello from CPP");
}
It just doesn't work. I still receive the error of undefined reference to _helloWorld in my main.c. Where is the the problem?
Short answer:
example.cpp should include example.h.
Longer answer:
When you declare a function in C++, it has C++ linkage and calling conventions. (In practice the most important feature of this is name mangling - the process by which a C++ compiler alters the name of a symbol so that you can have functions with the same name that vary in parameter types.) extern "C" (present in your header file) is your way around it - it specifies that this is a C function, callable from C code, eg. not mangled.
You have extern "C" in your header file, which is a good start, but your C++ file is not including it and does not have extern "C" in the declaration, so it doesn't know to compile it as a C function.
the extern "C" tells C++ that the declared function has to use the C ABI (Application Binary interface), hence, whether the language is C or C++, your void HelloWorld() is always seen externally as it is C.
But you implemented it in the cpp file like it is a C++ one, C is not aware of.
You have to make the prototype of HelloWorld coherent for both C and C++, so the cpp file should declare it as extern "C" void Helloworld() { /*your code here*/ }, or simply, #include "example.h" from example.cpp, so that, before implementing it, the compiler already knows it has to follow the C convention.
I am writing a (my first) C++ class on top of some code written in C, but I can only get the C++ to compile by declaring the C functions in a extern block. My project uses autotools; is there any way to automate this process so I don't have to maintain two header files?
Use a extern block inside a #ifdef in C codes header files
Start of header files
#ifdef __cplusplus
extern "C" {
#endif
...and at end of the header files
#ifdef __cplusplus
}
#endif
This way it will work for being included in both C and C++ sources
Yes create wrapper header files which include your C header files like so...
//Wrapper.h
#ifdef __cplusplus
extern "C"
{
#include "Actual.h"
}
#else
#include "Actual.h"
#endif
//Use.cpp
#include "Wrapper.h"
int main()
{
return 0;
}
//Use.c
#include "Wrapper.h"
/*or #include "Actual.h" */
int main()
{
return 0;
}
Use the C Preprocessor. Do something like this:
#ifdef __cplusplus
extern "C" {
#endif
// code goes here
#ifdef __cplusplus
}
#endif
We have a macro in a header file:
#ifdef __cplusplus
#define _crtn "C"
#else
#define _crtn
#endif
Then in header files, we can use _crtn:
#include "croutine.h"
extern _crtn void MyFunction( ... );
The only gotcha is to make sure you include the header file containing the prototype of MyFunction inside the file containing the implementation of MyFunction so that it is compiled with "C" linkage.
This is the same as #epatel's answer, but only requires the ugly #ifdef's in one header file.