I'm trying to include mongoose web server, which is written in C, and write the rest of the code in C++.
When compiling I get the error: redeclaration of C++ built-in type 'bool' in the mongoose header file in Code Blocks
#include <iostream>
#include "mongoose.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
return 0;
}
I enclosed the mongoose header in
#ifdef __cplusplus
extern "C"{
#endif
// header content
#ifdef __cplusplus
}
#endif
and I'm still getting the same error, at #include winsock2.h
C and C++ are different languages that share a common subset. You can compile most C declarations with a C++ compiler by putting them in a section specifying C linkage, as you show, but that follows from the sublanguage of C declarations being almost entirely within the shared subset of C and C++.
C++ has both more declarational features and more constraints than C does, however. In particular, the fact that it provides bool as a built-in type places a constraint that that identifier cannot be redeclared as a typedef name. C, on the other hand, has a standard header that defines exactly such a typedef, and it is not so uncommon for people to roll their own, too. Such typedefs will be rejected by a C++ compiler, C linkage notwithstanding.
If the C project is not already built with a mind toward providing for use by C++ programs, and simply wrapping the header inclusion in a C linkage block does not suffice, then you simply cannot use that library's header as-is. Your options are either to modify it or to provide an alternative. You might even need to provide a few wrapper functions, written in C, to serve as an interface with your C++ program. Details depend on the library you're trying to use.
If this is your only issue, then you could add #define bool C_INT_BOOL near your extern "C", then #undef bool near the }
In your cpp file I would write:
extern "C"{
#define bool C_INT_BOOL
#include "mongoose.h"
#undef bool
}
This allows the "C" interface to see the int parameter type, but shouldn't interfere with your c++ use of bool.
But I doubt this will be your only issue, in which case you will probaby quickly realise that adding an interface function layer is the safest way to go.
Related
I have a few questions about calling C standard library functions in C++:
If I want to call getline() which is declared in <stdio.h> is it always sufficient to just include <cstdio>? This works with the compiler I'm using and I see that it includes <stdio.h> in <cstdio> but I want to know if the standard guarantees this.
Are all C standard library functions guaranteed to be available in C++? With the getline() example from above I noticed that on cppreference under <cstdio> it doesn't list getline().
For C standard library functions and types that are made available in the std:: namespace like FILE or malloc() are they any problems with accessing them through the global namespace or is it just more idiomatic to access them as std::FILE or std::malloc()?
You should always include what the documentation tells you to. (C++ standard library implementations will often be written such that functions are reachable via other includes but of course relying on that means your code is not portable.) Note that there is no standard getline function in C. But there is one in C++:
std::getline()
is defined in header <string>. The C++ standard doesn't guarantee that, in general, C functions are available at global scope or are even part of the C++ standard library. The two languages began their divergence many years ago and so the idea that C++ is in a sense a superset of C - libraries included - is a myth.
Reference: https://en.cppreference.com/w/cpp/string/basic_string/getline
In relation to #3:
The .h libraries must place all its names in the global namespace and may also place them in the std:: namespace.
The c begining version must place all its names in the std:: namespace and may also place them in the global namespace.
It should be easy to link any C library with C++ in general, not just the standard headers.
Note that you may have to trawl through man to work out what version of what unix the method was introduced or if it is a specific extension, and decide for yourself if that historical startpoint is acceptable to you. But this is true if you wrote a C program instead of C++.
The C++ alias headers include most, but not all of the functionality from the C headers, but occasionally you may find the only way to get a function is to include the C header directly. On the other hand you need to ask yourself why they chose not to include that method, usually because it is deprecated, dangerous, or non-standard.
So the way it works, is that C functions, including C library functions are introduced with the extern "C" keyword.
When you #include C header files they will generally contain some code such as:
/* C++ needs to know that types and declarations are C, not C++. */
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
__BEGIN_DECLS
... which introduces a section of C interface functions.
If you needed to include a really old C library that did not do this, then you could easily add extern "C" around the #include:
extern "C" {
#include "ancientinterface.h"
};
You can also write your own methods that are "C" interface compatible.
I want to use this C++ Library in C-Code (and compile the code with gcc):
https://github.com/fairlight1337/libcflie
To do that I added Wrapper functions to CCrazyflie.h, CCrazyflie.cpp, CCrazyRadio.h and CCrazyRadio.cpp (all functions I want to use are in those Files):
Added to CCrazyRadio.h:
extern "C"
{
CCrazyRadio* newCCrazyRadio(string strRadioID);
void deleteCCrazyRadio(CCrazyRadio* cr);
int CCrazyRadio_startRadio(CCrazyRadio* cr);
}
Added to CCrazyRadio.cpp:
extern "C"
{
CCrazyRadio* newCCrazyRadio(string strRadioID) {return new CCrazyRadio(strRadioID);}
void deleteCCrazyRadio(CCrazyRadio* cr) {delete cr;}
int CCrazyRadio_startRadio(CCrazyRadio* cr) {if(cr->startRadio()) return 1; else return 0;}
}
I did the same thing for the functions in CCrazyflie.h and CCrazyflie.cpp.
I can use the wrappers in C-code and they work when compiled with g++, but when compiling with gcc the compiler complains that it doesn't know iostream (included in CCrazyflie.h and CCrazyRadio.h which are both included in my C-code).
Am I doing this right? How can I make gcc find iostream (and the other C++ libraries that are included)?
If needed I would be happy to show you more of the code, I just tried to keep the post short.
Thanks in advance for any help!
Regards,
Daniel
The problem is not the linker as some have suggested, or that the wrappers need to be compiled with a C++ compiler (although they do).
The issue is that the C file includes the header that defines the wrappers, and the wrapper functions take types that the C language doesn't have - eg string. The extern statement tells the C++ compiler not to mangle the names, but doesn't magically make anything inside legal C.
So, your wrapper functions need to be defined to take C types, so your
CCrazyRadio* newCCrazyRadio(string strRadioID);
becomes something like
CCrazyRadio* newCCrazyRadio(char * radioId);
And internally to newCCrazyRadio you can construct a string to hold your radioID, if needed. If CCrazyRadio is a class, you will still have troubles though. So, if this is just being returned as some sort of handle, you could perhaps replace with a void*
You still need the extern 'C'.
You will also need to ensure that the header containing the wrapper functions ONLY includes C header files. Even if gcc (in C mode) can find them, they will not contain valid C code. This means it cannot include iostream etc.
One further thing, I recall that C doesnt understand the extern C syntax, so you may need to wrap that with a conditional compiliation block eg (you will need to check the syntax your self)
#ifdef _CPLUSPLUS_ // Check this bit
extern 'C'
{
#endif
//Put your prototype wrappers here
#ifdef _CPLUSPLUS
}
#endif
This basically means that only the C++ compiler will see the extern C directive.
I have a C library that I need to use in a C++ code, so I need to wrap the whole lib with an extern "C" block. The problem is that the library seems to include a C++ compiled code, so wrapping the whole lib would also wrap that C++ header.
Inside lib.h I only include all the internal headers I want to expose, something like this:
#ifndef LIB_H
#define LIB_H
#include "lib_foo.h"
#include "lib_bar.h"
#include "lib_baz.h"
#endif
So the client will only need to include lib.h to use the lib.
In my first attempt I've done this:
#ifndef LIB_H
#define LIB_H
extern "C" {
#include "lib_foo.h"
#include "lib_bar.h"
#include "lib_baz.h"
}
#endif
But then I get a symbol lookup error when I execute any function inside already_compiled_c++.h.
How can I avoid from applying extern "C" in the already_compiled_c++.h header file?
Edit:
Solved. This was not a problem using extern "C", it was a problem linking the compiled c++ library with gyp correctly: Using shared library in Gyp in node-sqlite3
Note that extern C isn't legal C, so it must only be included hen compiling as C++.
The already_compiled_c++.h header probably contains a guard against multiple includes, so just include it first:
#ifndef LIB_H
#define LIB_H
# This include added so that it won't get marked extern "C" when included by lob_foo.h.
#include <already_compiled_c++.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "lib_foo.h"
#include "lib_bar.h"
#include "lib_baz.h"
#ifdef __cplusplus
}
#endif
#endif
Note: You need to check if already_compiled_c++.h is conditionally included and add the corresponding conditionals.
You cannot call C++ from a file compiled in plain C.
If lib_foo.h is plain C, it cannot directly use the functions in already_compiled_c++.h. You will most likely need to create a C wrapper for it.
This answer may help you further: Elegantly call C++ from C
If your diagram is accurate, then lib_foo.h should not be including already_compiled_c++.h. Edit it to stop including that.
If the functions declared in already_compiled_c++.h had their implementation compiled to use the C++ ABI, there is no way that your C program could link against them. (short of extremely ugly hacking).
To avoid snarls like this in the future, explicitly put #ifdef __cplusplus extern "C" { guards in every header file which will have a C implementation, but might be used in a C++ program, and vice versa.
A workaround for your current situation would be to make a .cpp file that has thunks for the functions you need. Publish your thunks under extern "C", and implement them by calling the functions in already_compiled_c++.h.
Rethink your design. You can't include C++ headers from C, only the reverse. A few suggestions:
1) Although the original idea behind 'extern "C"' was to wrap includes of C headers from C++ files, if you have headers that should be C-accessible but are implemented in C++, the common approach is to wrap the declarations in it and not the includes. (With the requisite #ifdef __cplusplus so the C code, which always treats headers as being C, doesn't choke on the unneeded C++-ism 'extern "C"')
2) Don't expose C++ as the public API of a library. C++ in general does not provide a binary stable ABI. If you add a method and it's not at the end, or if you add an instance variable to a class, or if you change something in a templated class, all clients would have to be recompiled (with static libraries that usually happens anyway, but this is a big problem for dylibs/DLLs/frameworks). So in general the best idea is to keep C++ as an implementation detail and only expose C features from your library.
3) If you need to expose C++ from your library, use the Pimpl (private implementation) pattern and no templates, and put it in a separate header that isn't included by the master C header, so C clients can just not include it. Such a separate header is also useful for #2 because your library's modules' implementation files (which are in C++) can include it and thus use the classes in it.
4) To C++, a pointer to a struct Foo and a pointer to a class Foo are the same thing. So if you need to return a C++ class from a C-only API implemented behind the scenes in C++, what you can do is just always use struct Foo* in the headers (which C understands correctly), and provide C wrapper functions for the class's methods like:
extern "C" int FooGetCount( struct Foo* thisFoo )
{
return thisFoo->GetCount();
}
That way they can keep around pointers to C++ objects and access their properties, but don't need to actually use C++. Of course you also need to provide similar wrappers for creating/deleting the object, as C doesn't have the new/delete operators.
I know how to use extern "C" but what are the conditions when you have to use it?
extern "C" tells the C++ compiler not to perform any name-mangling on
the code within the braces. This allows you to call C functions from
within C++.
For example:
#include <string.h>
int main()
{
char s[] = "Hello";
char d[6];
strcpy_s(d, s);
}
While this compiles fine on VC++. But sometimes this is written as:
extern "C" {
#include <string.h>
}
I don't see the point. Can you give a real example where extern "C" is necessary?
You use extern "C" to prevent name mangling inside header files and your C++ object files for libraries or objects that have already been compiled without mangling.
For example, say you have a widget library which was compiled with a C compiler so that its published interface is non-mangled.
If you include the header file as is into your code, it will assume the names are mangled and those mangled versions are what you'll tell the linker to look for.
However, since you'll be asking for something like function#intarray_float_charptr and the widget library will have only published function, you're going to run into problems.
However, if you include it with:
extern "C" {
#include "widget.h"
}
your compiler will know that it should try to use function, the non-mangled version.
That's why, in header files for C stuff meant to be included in C _or C++ programs, you'll see things like:
#ifdef __cplusplus
extern "C" {
#endif
// Everything here works for both C and C++ compilers.
#ifdef __cplusplus
}
#endif
If you use a C compiler to include this, the #ifdef lines will cause the extern "C" stuff to disappear. For a C++ compiler (where __cplusplus is defined), everything will be non-mangled.
One very common use of extern "C" when you are exporting a function from a library. If you don't disable C++ name mangling you can otherwise make it very hard for clients of your library to name your function. And likewise, when going in the other direction, when you are importing a function that has been exported with C linkage.
Here is a concrete example of where things break and need extern "C" to get fixed.
module.h:
int f(int arg);
module.c:
int f(int arg) {
return arg + 1;
}
main.cpp:
#include "module.h"
int main() {
f(42);
}
Since I am mixing C and C++, this won't link (of the two object files, only one will know f under its C++ mangled name).
Perhaps the cleanest way to fix this is by making the header file compatible with both C and C++:
module.h:
#ifdef __cplusplus
extern "C" {
#endif
int f(int arg);
#ifdef __cplusplus
}
#endif
When you link with libraries that are written in C extern tells the compiler not to decorate the names so that the linker can find the functions. In C++ function names et al have information for the linker e.g. argument types and sizes contained in the name.
If you are producing a binary library A that exposes a function that you would like to call from binary B.
Imagine A is A.dll and B is B.exe and you are on a Windows system.
C++ does not describe a binary layout such that B knows how to call A. Typically this problem is worked around by using the same compiler to produce A and B. If you want a more generic solution you use the extern keyword. This exposes the function in a C manner. C does describe a binary format so that different binaries from different compilers can talk to each other.
See:
http://en.wikipedia.org/wiki/Application_binary_interface
http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B
If, inside your C++ code, you #include a header for an external library (coded in C) and if the functions there are not declared extern "C" they wont work (you'll get undefined reference at link time).
But these days, people coding C libraries and providing header files for you tend to know that, and often put the extern "C" in their header file (suitably protected with #ifdef __cplusplus)
Perhaps a better way to understand is to use (assuming you have a Linux system) the nm utility to show you the (unmangled) names used in a library or an executable.
This question already has answers here:
What is the effect of extern "C" in C++?
(17 answers)
Closed 8 years ago.
Maybe I'm not understanding the differences between C and C++, but when and why do we need to use
extern "C" {
? Apparently its a "linkage convention".
I read about it briefly and noticed that all the .h header files included with MSVS surround their code with it. What type of code exactly is "C code" and NOT "C++ code"? I thought C++ included all C code?
I'm guessing that this is not the case and that C++ is different and that standard features/functions exist in one or the other but not both (ie: printf is C and cout is C++), but that C++ is backwards compatible though the extern "C" declaration. Is this correct?
My next question depends on the answer to the first, but I'll ask it here anyway: Since MSVS header files that are written in C are surrounded by extern "C" { ... }, when would you ever need to use this yourself in your own code? If your code is C code and you are trying to compile it in a C++ compiler, shouldn't it work without problem because all the standard h files you include will already have the extern "C" thing in them with the C++ compiler?
Do you have to use this when compiling in C++ but linking to already built C libraries or something?
You need to use extern "C" in C++ when declaring a function that was implemented/compiled in C. The use of extern "C" tells the compiler/linker to use the C naming and calling conventions, instead of the C++ name mangling and C++ calling conventions that would be used otherwise. For functions provided by other libraries, you will almost never need to use extern "C", as well-written libraries will already have this in there for the public APIs that it exports to both C and C++. If, however, you write a library that you want to make available both in C and in C++, then you will have to conditionally put that in your headers.
As for whether all C code is C++ code... no, that is not correct. It is a popular myth that C++ is a "superset of C". While C++ certainly strives to be as compatible with C as possible, there are some incompatibilities. For example, bool is valid C++ but not valid C, while _Bool exists in C99, but is not available in C++.
As to whether you will ever need to use extern "C" with the system's ".h" files.... any well-designed implementation will have those in there for you, so that you do not need to use them. However, to be certain that they are provided, you should include the equivalent header file that begins with "c" and omits ".h". For example, if you include <ctype.h>, almost any reasonable system will have the extern "C" added; however, to be assured a C++-compatible header, you should instead include the header <cctype>.
You may also be interested in Mixing C and C++ from the C++ FAQ Lite.
The other answers are correct, but a complete "boilerplate" example will probably help. The canonical method for including C code in C and/or C++ projects is as follows:
//
// C_library.h
//
#ifdef __cplusplus
extern "C" {
#endif
//
// ... prototypes for C_library go here ...
//
#ifdef __cplusplus
}
#endif
-
//
// C_library.c
//
#include "C_library.h"
//
// ... implementations for C_library go here ...
//
-
//
// C++_code.cpp
//
#include "C_library.h"
#include "C++_code.h"
//
// ... C++_code implementation here may call C functions in C_library.c ...
//
Note: the above also applies to calling C code from Objective-C++.
C++ compilers mangle the names in their symbol table differently than C compilers. You need to use the extern "C" declaration to tell the C++ compiler to use the C mangling convention instead when building the symbol table.
I use 'extern c' so that C# can read my C++ code without having to figure out the extra name mangling done when exporting a C++ dll function. Otherwise, there are extra nonsensical (or really, non-English) characters that I have to add at the end of a function entry point on the C# side in order to properly access a C++ function in a dll.
extern "C" {} blocks tell a C++ compiler to use the C naming and calling conventions. If you don't use this you will get linker errors if trying to include a C library with your C++ project because C++ will mangle the names. I tend to use this on all my C headers just in case they are ever used in a C++ project:
#ifdef __cplusplus
extern "C" {
#endif
/* My library header */
#ifdef __cplusplus
} // extern
#endif
You need to use extern "C" when you want to use the C calling convention in code compiled by a C++ compiler. There are two reasons for this:
You have a function implemented in C and want to call it from C++.
You have a function implemented in C++ and want to call it from C. Note that in this case you can only use the C part of C++ in the function interface (no classes, ...).
Apart from C this also applies when you want to interoperate between C++ and other languages which use the same calling and naming conventions as C.
Typically the declarations in a C header file are surrounded with
#ifdef __cplusplus
extern "C" {
#endif
[... C declarations ...]
#ifdef __cplusplus
}
#endif
to make it usable from C++.
C++ functions are subject to name mangling. This makes them impossible to call directly from C code unless extern "C" is used.