Two dynamic libraries, one in C other in C++, using eachother - c++

Hoi,
I have a dynamic library loader, which is written in C++ but provides a C-compatible API.
That loader can load modules, which are written in any programming language. They're arranged in a named list and can request function pointers of other modules. Now, a module written in C and compiled with a C compiler gets the functions pointers of any other module, which is written and compiled in C++.
So my question: Are function-pointers cross-compiler valid? I think I heard of something like __cdecl once, long time ago. I use Linux 64bit.
T.I.A.

// my C++ code ...
extern "C" {
void thisFunctionWillBeCallableFromC();
}
void butThisOneMayNot();
struct S
{
void thisDefinitelyWontBeCallableFromC(std::map<int, S>);
};
C++ code should declare interfaces with extern "C" linkage to be callable from C.
Or do you mean C++ code generated by different compilers?

Function pointers are compatible between C and C++.
The only limitation, is that you have to declare your C-functions with extern "C" linkage when used within C++:
extern "C"
{
int foo();
}

Related

Calling C++ from C in a freestanding way

I have a kernel attempt written in C++, and I was wondering about porting it to x86_64 UEFI, but the EFI bootloader, that uses the GNU-efi lib, must be written in C.
How can I jump to the main kernel function from C? Using extern C all the way makes the use of the C++ characteristics impossible, maybe some assembly code could be used, or I could make the bootloader call an ELF file that would be the main kernel with an ELF loader. Are this solutions viable?
Using extern C all the way makes the use of the C++ characteristics impossible
It doesn't. There are no problems to write extern "C" in the header and compile your functions with a C++ compiler and use all kinds of C++ features in a separate translation unit.
You just need to avoid the C++ name mangling for the C++ implementation of your entry function. That's what extern "C" does, if you use it for the function declaration.
Here's a small example:
kernel.h
extern "C" void main_entry_point();
kernel.cpp
#include "kernel.h"
void main_entry_point() {
// use std::string, std::vector, etc.
}
bootloader.c
#include "kernel.h"
// call main_entry_point()
main_entry_point();

extern "C"---when *exactly* to use? [duplicate]

This question already has answers here:
When to use extern "C" in simple words? [duplicate]
(7 answers)
Closed 9 years ago.
If you're tempted to flag this question as a duplicate, please note that I've read the questions on this subject, yet something still is unclear to me. I'm under the impression that this construct is used when including C headers and linking with C code (please do correct me if I'm wrong). Does it mean that I never have to use "extern C" when not dealing with object files? If I'm wrong about that, why can't the old C code just be compiled as C++, as most likely it's legal c++ code anyway?
I'm a bit iffy about it because I swear I've had situations when working with old C source code in C++ where a linker error is solved only with "extern C", and library headers do have
#ifdef __cplusplus
#extern "C"{
#endif
//......
#ifdef _cplusplus
}
#endif
around them.
EDIT: sorry for being unclear, but what I meant to ask is that whether it's true that "extern C" is only needed when including C headers and linking with pre-existing C object files? If it's true, (and it seems to be judging from comments below), why do library headers have "extern C" clauses around them, why can't they just be included and compiled as C++?
Name mangling rules are different for C. And C can have a different ABI than C++. These reasons alone require you to use extern "C" when embedding C code in C++ code. Even if a compiler can compile both C and C++ code, it might use different name mangling rules or ABIs for the two languages.
Also, your assertion that "[C code is] most likely ... legal c++ code" is not quite true, as C and C++ have diverged more and more as the years have gone on. They have a lot of similarities, but they also have a good number of differences.
The library itself is a C object file, therefore in order to use it your application has to expect a C-ABI for calling the functions in the library and you need to provide the appropriate hint to the compiler when you prototype the functions.
extern void libraryFunc();
If the library is actually compiled as C, which is the only way it can support C and C++, then you need to include annotation for C++ compilers that this MUST be linked as C.
#ifdef __cplusplus // only true when compiling with a C++ compiler
extern "C" {
#endif
extern void libraryFunc();
#ifdef __cplusplus
}
#endif
To a C compiler, this reads
extern void libraryFunc();
To a C++ compiler, this reads
extern "C" {
extern void libraryFunc();
...
}
which is equivalent to
extern "C" void libraryFunc();
If the duplication of extern bothers you, consider:
#if defined __cplusplus
# define C_EXTERN extern "C"
#else
# define C_EXTERN extern
#endif
EXTERN_C {
void foo();
}
The compiler and linker now know to use the C ABI when trying to call/link that function.
Note that the C++ ABI is a superset of the C ABI (application binary interface) so if you want to share code, C is the LCD and needs to be your common interface. C is completely unaware of C++ "name mangling" etc.
This is essentially answered here: When to use extern "C" in simple words?
But the pertinent point is that, when compiling in C++, the names of functions are "mangled" to encode certain information about the function (like argument types). Since C++ always mangles a function name the same way, everything is consistent between the mangled name call and what is put in the object file.
If you compile a file in C called "foo", and in your C++ file you have extern foo(int c);, the C++ compile will have mangled "foo" into something different, for example, foo__Ic (I just made it up, the actual mangling will look different).
Meanwhile, in the plain C code compiled with the C compiler, the object code has defined symbol that is simply foo.
However, when the whole thing is linked, the C++ code has an external symbol foo__Ic that it's trying to resolve, which does not match the defined symbol foo in the C object file.
Hope that helps.
There's another case not mentioned yet. extern "C" specifies the C linkage, but C is not the only other language. C linkage is also used by other languages which are too obscure to have their own widely accepted linkage. E.g. Java uses C linkage, too. Obviously you can't compile that Java code with C++, so you do need extern "C" on the C++ side.

How I can access my C++ function in my C code or vice versa?

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

better understanding of extern "C" functions

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.

Why would you use 'extern "C++"'?

In this article the keyword extern can be followed by "C" or "C++". Why would you use 'extern "C++"'? Is it practical?
The language permits:
extern "C" {
#include "foo.h"
}
What if foo.h contains something which requires C++ linkage?
void f_plain(const char *);
extern "C++" void f_fancy(const std::string &);
That's how you keep the linker happy.
There is no real reason to use extern "C++". It merely make explicit the linkage that is the implicit default. If you have a class where some members have extern "C" linkage, you may wish the explicit state that the others are extern "C++".
Note that the C++ Standard defines syntactically extern "anystring". It only give formal meanings to extern "C" and extern "C++". A compiler vendor is free to define extern "Pascal" or even extern "COM+" if they like.
I'm not sure why you would need to do it, but according to this article from Sun, you can use extern "C++" inside a block of extern "C" to specify certain functions in a group of "C" functions have the native C++ linkage.
extern "C" {
void f(); // C linkage
extern "C++" {
void g(); // C++ linkage
extern "C" void h(); // C linkage
void g2(); // C++ linkage
}
extern "C++" void k();// C++ linkage
void m(); // C linkage
}
Two guesses:
If you are in a extern "C" block, you can get C++ language linkage again by specifying a nested extern "C++".
It reserves C++ linkage, because it's the document defining C++. Who is in a better position for defining C++ language linkage than it itself. It also provides for completeness. Same deal as with signed/unsigned.
Read this answer that explains extern "LanguageName" (i.e GCC has extern "Java") aswell.
Extern "C" is answered by many. The use case for extern "C++" is when calling C++ library function in a C function. The sub-use case, that is relevant, is when linking a C++ library with a C source code with main function. Check this wiki page for more details:
C and C++ use different name mangling rules. Essentially, extern "C" tells the C++ compiler to name the function as C would name it.
This specify which link convention to use. Most languages know how to link with a "C" style function.
You need this in two cases :
A C - or other languages for that matter- program calling a function written in C++
A C++ program calling a function written in C
Example :
// declared in function.h
void f1(void);
Your C code - actually other languages are able to link with C function - will not be able to link to it because the name in the object table will use C++ convention.
If you write
extern "C" void f1(void);
Now the linking works because it uses C convention.
The #1 reason I use extern "C" is to avoid C++'s name mangling rules. This is very important if you are working in a .Net language and want to PInvoke into a particular native function. The only way to do this is with name mangling disabled.
To answer the second question, "is it practical?":
It is practical, and practically unavoidable, in standard headers like <cmath>.
Imagine a header-only library X.h, written in a common subset of C++ and C, and intended to be used from both languages. For the benefit of C++ users, X.h includes <cmath>, not <math.h>. This would not work for C users though, hadn't the authors of <cmath> sandwiched everything in extern "C++" { ... }.
Short answer is that you can use extern C to tell the compiler not to use name-mangling. This means you can link together bits of C and C++ code in the same project.
extern "C" is used to say that a C++ function should have C linkage. What this means is implementation dependant, but normally it turns off C++ name-mangling (and so overloading and strict type checking). You use it when you have a C++ function you want to be called from C code:
extern "C" void Foo(); // can be called easily from C
As for extern "C++", I've never seen it in real code, though the C++ Standard allows it. I guess it is a no-op.