Can I make function `extern "c"`? - c++

I have some cpp files, and I want to combine them with LuaJit using FFI.
But the problem is that, I have to add extern "c" symbols for almost every function to make it possible for FFI to access them.
Is there a simpler way to make this done?

Several functions can be placed inside a single extern "C" block. This allows you to type extern "C" only once for each header file.
extern "C" {
void function1();
void function2();
}

Though it is non-portable, you could implement a function signature and generates the Mangled name using the name mangling protocol to find the symbol name for FFI.
Gcc and Clang on Linux use the Itanium C++ ABI Name Mangling Rules, which can be found here.
On Windows, MSVC uses a non-documented name mangling scheme.

Yes. Define a simple, minimal, wrapper API and export it:
// NOTE: Exported functions do heavy parley and medical-research leveraging C++ under the hood (and only and the hood).
extern "C" {
void achieve_world_peace(void);
void treat_cancer(void);
}

Related

Calling a global function defined in C++ source file , from a C source file

Is there any way to call a C++ function from a C source file , without using extern "C" prior to the function declaration in the C++ file e.g :
//C++ source file
extern "C" void func_name();
void func_name()
{
....
}
The only way to not use extern "C" directly is to manually determine the mangled name and call that from C; which is essentially just doing extern "C" but manually. There's no point or purpose or alternative method with any merit whatsoever.
I'm not aware of any combination of C and C++ compilers that provide an officially supported way to do this. You're supposed to use extern "C" in the C++-side header files.
However, perhaps you have to anyway; I can think of several reasons other than homework, such as when you've got a third-party C++ library with an interface that could be invoked from C but the developers neglected to put extern "C" in the headers, and you can't recompile it.
There is usually an unofficial way to do it: you have to find out the mangled name of the C++ function, and any hidden parameters that it has (this is almost always treated as a hidden first parameter, and there may be others). You then write a declaration on the C side using the mangled name and the full parameter list.
Here is a very simple example that will work with GCC on most operating systems and CPUs:
/* file1.cpp */
#include <cstdio>
void foo()
{
puts("hello from foo");
}
/* file2.c */
#include <stdio.h>
extern void _Z3foov(void);
int main(void)
{
puts("hello from main");
_Z3foov();
return 0;
}
Because this is homework I am not going to give you a more complicated example, but I am going to point you at the so-called "Itanium C++ ABI", which specifies how the mangling and the hidden parameters work with GCC and Clang on most operating systems and CPUs. (Be aware that MSVC uses a completely different, undocumented, scheme. I have heard rumors that Clang can optionally use MSVC's scheme now but I'm not sure I believe it, considering how gargantuan a reverse-engineering job it would have been. ;-)
(In case you're wondering, mangled names are how function and operator overloading are implemented in the linker. If my file1.cpp had defined both void foo(void) and void foo(int), that would have produced an object file exporting the mangled names _Z3foov and _Z3fooi.)
You could write a separate translation unit, let's say mycppunit.cpp containing your void func_name() implementation without any extern "C" declarations. Compile this translation unit into a binary using a C++ compiler, yielding, for example, a mycppunit.o binary; then, use a command line tool like nm to find out how the function name has been mangled: For example:
nm mycppunit.o | grep func_name
would give something like
000000010006a920 T __Z9func_namev
Then you may assume that there will be a function void _Z9func_namev() available, and you can write in a translation unit, e.g. `my_c_program.c, the following:
void _Z9func_namev();
int main() {
_Z9func_namev();
}
Compiling this with a C compiler and linking it together with the mycppunit.o will give the desired result.
Hope it is what you are looking for.

Using dlsym in c++ without extern "C"

I have a system in which I give the user a function prototype and the user has to implement it. Now, I compile this file using g++ and load it dynamically using dlopen and dlsym to process it further. Now, I read here:
c++ dlopen mini-howto
that to load c++ functions we have to use extern "C" before the function. Now, the problem is, I do not want to show the user how things are working. I do not want to show the user extern "C" before the function.
Is there any way to avoid it?
You can use the mangled C++ name directly.
If you have e.g. a C++ function void my_plugin(int foo) , the C++ compiler will mangle that name.
Once you know the mangled function name, you can use dlopen() on that name.
e.g.
# nm libmyplugin.so |grep my_plugin
00000000 T _Z9my_plugini
So here our function is named _Z9my_plugini , and you could do
func = dlsym(handle, "_Z9my_plugini");
Traditionally different compilers could mangle the name in different ways, so this could be quite fragile, thoug these days most C++ compilers will aggree opon a standard way of mangling the names on a given platform.
However your users will be programmers, and they would normally have an understanding of exposing an entry to a dynamically loaded library as extern "C"
Since you are using C++, why don't you export only one (or two) functions that will simply return a pointer to some kind of pure virtual class, say IMyModule? The one (or two) exported extern "C" functions would be something similar to extern "C" IMyModule * create_instance_IMyModule(); (and extern "C" void delete_instance_IMyModule(IMyModule const *);).
Another alternative to extern "C" before each declaration is to use the block-style syntax:
extern "C" {
void my_callback();
int other_functionality( foo * );
}
Often the extern "C" { and closing brace } are wrapped in macros, which are conditional on the __cplusplus built-in macro, so the header can also be used from pure C. This also encapsulates the part you find objectionable.
In any case, I don't see what the big deal is. If the user can write in C++, they should be competent to enclose their C interface function prototypes in extern "C" when the library documentation tells them to.

When to use extern "C"?

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.

When is "extern C " necessary in c++ in windows?

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++.

Why do you need "extern C" for C++ callbacks to C functions?

I find such examples in Boost code.
namespace boost {
namespace {
extern "C" void *thread_proxy(void *f)
{
....
}
} // anonymous
void thread::thread_start(...)
{
...
pthread_create(something,0,&thread_proxy,something_else);
...
}
} // boost
Why do you actually need this extern "C"?
It is clear that the thread_proxy function is private internal and I do not expect that it
would be mangled as "thread_proxy" because I actually do not need it mangled at all.
In fact, in all my code that I had written and that runs on many platforms, I never used extern "C" and this had worked as-is with normal functions.
Why is extern "C" added?
My problem is that extern "C" functions pollute the global namespace and they are not actually hidden as the author expects.
This is not a duplicate!
I'm not talking about mangling and external linkage. It is obvious in this code that external linkage is unwanted!
Answer: The calling conventions of C and C++ functions are not necessarily the same, so you need to create one with the C calling convention. See 7.5 (p4) of C++ standard.
It is clear that the thread_proxy function is private internal and I do not expect that it would be mangled as "thread_proxy" because I actually do not need it mangled at all.
Regardless, it's still going to be mangled. (Had it not been extern "C") That's just how the compiler works. I agree it's conceivable a compiler could say "this doesn't necessarily need to be mangled", but the standard says nothing on it. That said, mangling doesn't come into play here, as we aren't trying to link to the function.
In fact, in all my code that I had written and that runs on many platforms, I never used extern "C" and this had worked as-is with normal functions.
Writing on different platforms has nothing to do with extern "C". I expect all standard C++ code to work on all platforms that have a standard C++ compliant compiler.
extern "C" has to do with interfacing with C, which pthread is a library of. Not only does it not mangle the name, it makes sure it's callable with the C calling convention. It's the calling convention that needs to be guaranteed, and because we can't assume we are running on a certain compiler, platform, or architecture, the best way to try and do that is with the functionality given to us: extern "C".
My problem is that extern "C" functions pollute the global namespace and they are not actually hidden as the author expects.
There's nothing polluting about the above code. It's in an unnamed namespace, and not accessible outside the translation unit.
extern "C" linkage does not necessarily mean that only name mangling is suppressed. In fact, there may be a compiler which treats extern "C" as a different calling convention.
The standard leaves this completely open as implementation-defined semantics.
The question is valid - although the function is being passed to a C library, that C library is not linking to the C++ code at all. It is only given the address of the function, so it has no interest at all in the name of the function.
The point is that extern "C" is the closest thing there is to a cross-platform way of telling the compiler to make the function use the standard C calling convention on that platform (i.e. exactly how parameters and return values should be passed on the stack).
It is unfortunate that it also has the side-effect of creating an extern linker symbol at the global level. But this could be mitigated by using a name like boost_detail_thread_proxy instead.
It's being used to make the function use whatever the compiler understands by the C calling convention while avoiding compiler specific keywords such as __cdecl.
That's all there is to it. It's got absolutely nothing to do with name mangling, namespaces or any of the other weird answers here (as you already knew when you asked).
Probably because you are interfacing a plain C library -- pthreads.
Since C and C++ are not guaranteed to have the same calling convention, you need to declare the callback function as extern "C" in order to pass it into the pthread_create C function.
The thread_proxy function above has external linkage (i.e. is visible outside its translation unit) because namespaces have no impact on extern "C" functions -- even anonymous namespaces. Instead, to give the thread_proxy function internal linkage, you need to declare it as static:
namespace boost {
namespace {
extern "C" {
static void *thread_proxy(void *f)
{
....
}
} // extern "C"
} // anonymous
...
} // boost
[Edit] Note that boost has incorporated this change. See https://svn.boost.org/trac/boost/ticket/5170.