As we know that we can use c functions directly in c++, when is extern "C" necessary then?
If your function is implemented in a .c file, the .cpp files will need the extern "C" reference, or else they'd reference a mangled C++-style function name, and the link would fail.
It's also handy for exporting functions from DLLs so that they are exported with a non-mangled name.
It's necessary when a C++ function must be called by C code rather than C++ code.
Basically, when you want your C++ library to be backwards compatible.
There are two rather different uses for extern "C". One is to define a function in C++ that you should be able to call from C. I.e., you're writing code in C++, but it needs to interface with C code. In this case, you define the function as extern "C":
extern "C" {
int c_callable_func1() {}
int c_callable_func2() {}
}
When you do this, the interface of those functions must follow pretty much the same rules as they would in C as well (e.g., you can't overload the functions or use default values for any parameters).
The other (considerably more common) situation is that you have code written in C that you want to be able to call from C++. In this case, the function definitions remain exactly as before, but the functions need to be declared/prototyped as extern "C". In a typical case, you want to use a single header that can be #included in either a C or C++ file, so the structure looks something like this:
// myheader.h
#ifndef MY_HEADER_H_INCLUDED_
#define MY_HEADER_H_INCLUDED_
#ifdef __cplusplus
extern "C" {
#endif
int func1(void);
void func2(int);
#ifdef __cplusplus
}
#endif
#endif
So, a C++ compiler will see function declarations (and typedefs, etc.) surrounded by an extern "C" block, while a C compiler will see prototypes, not surrounded by something it doesn't recognize.
In the first case (C++ functions callable from C), you'll normally structure the header roughly the same way, so you can also call those functions from C++ if necessary (but at the interface, you still lose all extra features of C++ like function overloading).
As you know that c++ support function overloading, which define the same function or method many times with different parameters. To do this, the compiler has to add some part of symbols for each one ... for example, the compiler will change the function name foo in the following declaration
from
void foo(int f,char c);
to
foo#i&c
Unfortunately, C doesn't support this. All function names remain the same after compiling it. So, to call a c++ function from c, you have to know the exact name after the modification and I think it's hard and different from a compiler to another.
to work around this and be able call c++ function from c and stop the compiler from changing the names you have to use this keyword like
extern "C" {
void foo(int f,char c);
}
that's it !!!
Because the function signatures generated by C and C++ compilers differ -- this sets up the C convention for C function even when using C++.
Related
Is there a difference whether I use the extern "C" specifier for the entire header, or specify extern for every function?
As far as I know, there is none, since only functions and variables can be linked externally, so when I use the extern specifier before every function prototype and extern variable, I have no need to use the global extern "C" declaration!?
Example A:
#ifdef __cplusplus
extern "C" {
#endif
void whatever(void);
#endif
Example B:
extern void whatever(void);
The presence of extern "C" in a C++ file allows to call the particular C++ function from a C client caller code.
What is the difference?
A long, long time ago C-compilers generated code and addressed functions by name only.
It didn't consider parameters.
When overloaded functions were introduced in C++, extern "C" was required to specify the same name for different functions. For example void f() and void f(int) are two different functions in C++.
The C++ compiler accomplished this via name-mangling. It adds some info to the function name related to the functions parameters.
extern "C" is a command to the compiler to "refer to the older style naming convention - without mangling".
There is a difference between those two things.
The first says "the functions in here should be compiled so as to be callable from C". C++ allows multiple functions to have the same name as long as they take different arguments. C does not. To achieve that, C++ includes argument type information in the compiled name of its functions. As a result a C compiler will not be able to find the functions. If you add an extern "C" then you instead get C behaviour, but you gain the ability to call those functions from C.
The latter says "this function exists in another compilation unit". Which means that a compiler should trust that the function with that signature exists but not worry about being unable to see it. It'll be there when you link, you promise. Declarations (contrasting with definitions) are extern by default since at least C99.
I want to implement a project in C, but it is comfortable to code some part of project in C++ and then call them from main C code.
Is it possible?! if yes, how I can do it?!
thanks in advance :)
P.S.
I used some libraries in my C++ Code such as OpenCV.
You'll need to "wrap" your C++ interface with regular C functions that take a parameter to indicate what object they'll be called on. For instance, if you have in C++
class A
{
// .. boilerplate stuff...
int SomeMethod(int n, float f);
};
Then along with it, you could declare a function such as
extern "C" int A_SomeMethod(void* Obj, int n, float f)
{
return(((A*)Obj)->SomeMethod(n, f));
}
If you're not comfortable with the casting of the void*, you can implement some kind of map from an opaque handle to an A*. But the gist is you'll need to keep around some handle/pointer to the object that the method will be called on. In order to get the pointer/handle you'll need to wrap the allocation to:
extern "C" void* A_Instantiate()
{
return new A;
}
The C++ files should be compiled separately along with the file with the functions above. A separate include for the C compilation should include declarations of all the functions above.
EDIT: The caveats and comments below are important; to answer the question, "Yes it is possible to call C++ from C", and this is one approach. It's not a complete approach as there isn't really a mechanistic way to do it, but it's a start. Also, don't forget to create another call-through for delete, etc, etc.
Q: Can I access my C code from C++ or vice versa?
A: Yes.
1) The main thing is to use extern "C" { ...} in all your headers to denote C-only functions and data, like this:
http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B
/* Header file foo.h */
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
/* These functions get C linkage */
void foo();
struct bar { /* ... */ };
#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
}
#endif
2) The usual scenario is a C++ main program that calls a mix of C and C++ functions and structs. The structs and functions are all declared in headers, and all have "#ifdef __cplusplus/extern C".
3) Here is a good FAQ on mixing C and C++:
http://www.parashift.com/c++-faq/mixing-c-and-cpp.html
Unless strictly required, this is only for dyied-in-the-wool masochists. Doing it will require extreme care on both sides, and could well work today and explode spectacularly with the next compiler update. C++ requires a lot of runtime help, and getting that to work reliably from C isn't normally supported. You can call into C from C++, that is officially supported (and part of the standard, extern "C" and such).
Probably the best bet is to write your C in the subset handled by C and C++ (a starting point on the subtle differences is this) and compile with the C++ compiler. Or get over it and decide what language you like most.
yes, you need to specify it as
extern "C"
this way it will make the function to have "C" linkage, then C code can call your function just as if it was in C. This function name will not be mangled then because C doesn't support overloading.
here let me cite #Faisal Vali:
extern "C" is a linkage-specification
Every compiler is required to provide "C" linkage
a linkage specification shall occur only in namespace scope
all function types, function names and variable names have a language linkage
two function types with distinct language linkages are distinct types even if otherwise identical
linkage specs nest, inner one determines the final linkage
extern "C" is ignored for class members
at most one function with a particular name can have "C" linkage (regardless of namespace)
extern "C" forces a function to have external linkage (cannot make it static)
Linkage from C++ to objects defined in other languages and to objects defined in C++ from other languages is implementation-defined and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved
see Faisal Vali answer here
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.
I am just trying to further understand extern C functions.
According to my knowledge, an extern C function is always a function you are trying call from an application that has already been compiled. Either a executable, static or dynamic library.
extern "C"
{
HRESULT CreateDevice();
typedef HRESULT (*CREATEDEVICE)();
HRESULT ReleaseDevice();
typedef HRESULT (*RELEASEDEVICE)();
}
So my question is...
Is my understanding correct ??
Does it always have to be a C function pointer ??'
Why must you use a typedef for each function ??
I presume that when you use the GetProcAddress(). You are allocating memory on that particulars applications HEAP and not the one you are calling it from. Therefore you must release it from that heap as well ??
extern "C" has 2 implications. First, it declares that the symbolic names of the functions are not "name mangled" to support C++. Second, it tells the compiler that the function is called using the C calling convention rather than the PASCAL calling convention. The difference has to do with when the return address is pushed on the stack. Using the wrong calling convention will crash your app.
This declaration is for the compiler, not the linker. So the extern C function could exist in your own modules or in a binary library: the source of actual bytes for the function implementation are resolved by the linker. If the function signature is declared as a regular C++ function and not extern C, the compiler will mangle the symbolic name to encode type information from the function signature. This will make it incompatible with object code generated by other C++ compilers. Therefore creating an extern C function allows you to share code between compilers in binary form. Note that you can't expose member functions this way, only old-style C functions.
It doesn't have to be a function pointer. You can specify the function declaration normally and prefix it with extern "C", as shown in some Microsoft examples.
If you use GetProcAddress() you are not allocating any memory. You simply get the memory address of the function inside the DLL that has already been loaded into memory (with LoadLibrary(), presumably).
Even when using function pointers (such as those returned by GetProcAddress) you don't have to use typedef, it's just that the code looks pretty ugly without it. It's always hard to figure out what to write as well. I think it would be something like:
void (*pReleaseDevice)() = (void (__cdecl *)(void))GetProcAddress(hInstance, "ReleaseDevice");
extern "C" {} is a C++ convention to declare that the enclosed functions are C functions -- not C++ functions. C++ has a slightly different naming convention which conflicts with C. If you have a library written in C and want to use it in a C++ program, you have to use extern "C" {} to let the compiler know these are C functions. If the library was written in C++ I believe the extern "C" {} will cause an error.
Note that extern has multiple meanings -- this specific case is a C++ convention and is unrelated to different uses of extern. For example,
extern int count;
has a completely different meaning than extern "C" {}.
The typedef is separate from the extern "C" {} issue. typedefs let you create aliases for common types that make more sense. For example, declaring structs is often a verbose process. I can use a typedef to shorten it:
struct mystruct {int a; int b};
typedef struct mystruct returncode;
// I can now declare a variable as type 'returncode'
returncode a;
Thus, in your example the HRESULT is really an alias for (*CREATEDEVICE)() although I believe you have to put it before the function (and not after).
One important aspect of specifying extern "C" linkage is that the function names do not get mangled, which is the default for C++ names.
In order for your library's functions to be able to be loaded using GetProcAddress, you need to either add the function to the .def file, use __declspec(dllexport) or use extern "C".
To answer, in order:
extern "C" functions are used for interop with C from C++. Using them has the consequence that C code can call the function. As the windows API is a C API all functions are extern "C" to ensure that C and C++ code can make use of the API.
In order for c++ programs to interoperate with other languages, including C, as a convention , functions are exported using extern "C". Which is why a lot of dll code does this. It is not a technical requirement however.
So no, it does NOT have to be a C function pointer.
You don't have to use typedef's either.
The example code provided is from a header file that is publishing the exports of a DLL twice - Once as the set of extern "C" methods that are exported so that the dll can be statically linked. the other as a set of function pointer types, so that the dll can be dynamically loaded, and the function pointer types used with GetProcAddress.
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.