Export a function with a c-style name? - d

Such that on windows, in C, I could do like so
void (*add)(int,int) = GetProcAddress(hDlangMod, "add");
add(422,244);

You can add extern (C) to remove name mangling if that's what you want, be aware that it will remove some features like overloading on the D side, but if you need the function being easily accessible from C, its a great solution! You can read more about it and other techniques in https://dlang.org/spec/interfaceToC.html
TLDR: Just define it as extern (C) void GetProcAddress(your params here) and link it appropriately, and it will work.
Note: The same extern directive can be used to import symbols from C or export to C++, along with other languages and uses, its quite a useful tool!
For example: https://dlang.org/spec/cpp_interface.html

Related

Can I make function `extern "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);
}

Is it possible for a C method not be able to be included in a C++ project?

I know I can include C methods inside a C++ project using the extern "C" thing. But lets us now suppose that I'm thinking in creating a C++ project that would use quite a lot of C methods coming from both libraries made by me as well as libraries made by other people/companies whose developing details and compilation specifications I'm simply not aware of.
Is it possible that some of this methods of C libraries, with unknown compilation and configuration details, could not be included in my C++ project with extern "C"? Or are all C methods necessarily 100% compatible with C++ code insofar extern "C" is used?
It's possible that some of the functions exported by C use names that collide with C++ keywords. You wouldn't be able to declare those using extern "C".
Functions exported by assembler could even use names that conflict with C keywords.
Those and functions declared static can still be called via function pointer, as long as the library gives you a way to get one.
Headers might not be parse-able in C++ mode for the same reasons -- things like the restrict keyword.
Other than naming issues, C++ has full support for the C calling convention. That's what extern "C" is all about.
C has constructs for interfaces that are not compatible with C++, in particular variable length arrays. In modern C you would write
void matMult(size_t n, size_t k, size_t m, double A[n][k], double B[k][m], double C[n][m]);
this interface can not be included as such in C++ compilation units.
Although rather unlikely, one possible issue that might arise with extern "C" in-place is when a function pointer declared extern "C" points to a C++ function that is not declared extern "C". See the last part of this page for more details.

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.

shared library symbol names

I would like to be able to use C/C++ functions from python using ctypes python module.
I have a function int doit() in the .c / .cpp file. When I try to load the shared library:
Frr=CDLL("/path/FoCpy2/libFrr.so")
Frr.doit(c_int(5))
i find it working really well when the .c variant is used. When C++ is called the good way to call this function is (found out using nm libFrr.so using nm -gC libFrr.so produces just plain doit()):
Frr._Z4doitv(c_int(5))
I have read on Stackexchange that there is no standard way to call C++ from python, and there is "nonstandard name mangling" issue. Is the "Z4" a part of that issue? I guess the nonstandard name mangling would appear for more advanced language features such as class methods, templates, but also for such basic functions? Is it possible to force using simple C function names in simple cases for the C++ code?
You can use extern "C" to make the functions "look like" C functions to the outside world (i.e., disable name-mangling). And yes, you are correct, name-mangling is needed mostly for the more complicated features and types of functions that C++ has, and the name-mangling scheme has never been standardized (nor the binary compatibility) and so it varies from compiler to compiler and between versions (but most main-stream compilers have settled to something permanent now, but still different between compiler-vendors). And the reason that mangling is also required for plain old free functions is because C++ supports overloading (same function names but with different parameters), and thus, the compilers will encode the parameter specification (e.g., types) into the mangled names. Of course, if you use extern "C" you lose all features for which name-mangling is needed, so, it more or less boils down to C functions only.
You can use extern "C" either on a per-function basis, like so:
extern "C" int doit();
Or for the overall header:
extern "C" {
// all the function declarations here ...
};
However, for Python specifically, I highly recommend that you use a library that allows you to construct Python classes and functions that are a reflection of your C++ classes and functions, that makes life a lot easier and hides away all this extern "C" business. I recommend using Boost.Python, see this getting started page, it makes exporting functions and classes to Python a breeze. I guess others would also recommend SWIG, but I have never used it.
Calling c++ library functions is always a mess, actually even if you're using C++ you have to use the same compiler, etc. to make sure it works.
The only general solution is to define your c++ functions as extern "C" and make sure you follow the involved limitations - see here for an explanation of it.

Question about c++ naming conventions

I'm trying to create a abstraction layer for platforms such as win32, mac os, linux, iOs etc.
I want this to be dynamically linked. On platforms that don't support this it shouldn't be a problem since from what I've seen everything that can be compiled as a dynamic library can be compiled as a static one as well with minimum impact on the code.
Now, to get to the point of this:
I created a interface named IThread and a class named CThread. I use a function named CreateThread that's defined with extern "C" to be able to export it and call it outside the library. The problem here is that in win32 for example there already is a function named CreateThread and thus I get a linker error. I understand the error and why it's appearing but I'm not sure of a good way to avoid this. I don't really like to use weird naming as qt uses like CreateQtThread.
Another idea I have would be is to create a thread manager/factory that creates instances of CThread but I'm not sure this would be a great idea.
What do you guys think about this? I'm asking because I don't want to rush on important organizing problems like this.
Thank you very much
I use a function named CreateThread that's defined with extern "C" to be able to export it and call it outside the library.
This is bad. I can't talk for other platforms, but on windows it's perfectly fine to export C++ functions. They are just get mangled, and you get some sanity checking in case someone changes the declaration. In fact, it's the only correct way to export a function that is C++. If you declare it as extern "C" you get no namespaces, no overloading, and someone who compiles with /EHsc will be in trouble if an exception escapes from your function.
Preferred solution: Do not declare them as extern "C", and put them in a namespace.
The only other solution: well, guess why all those C libraries prefix their functions with their_lib_prefix_function...
Your decision to use extern "C" is sound in my view because it allows access from other languages, compilers etc. But doing so means you can't use namespaces so you simply must prefix your functions with something to identify them as being from your library, a poor man's namespace if you will.
This is the compromise you must make if you want to use extern "C".
Well, I don't know whether you will like this as I know the C developers I worked with found it unaesthetic. But, it's very simple and prevents collisions like this. (More or less mentioned in this answer with the "their_lib_prefix_function" comment.)
So, whenever I was using C code, I used to basically 'namespace' my functions using an underscore. So, let's say your namespace is MegaAbstraction, then something like CreateThread becomes MegaAbstraction_CreateThread. Easy peasy. And no collisions, unless someone else has a namespace called MegaAbstraction in which case I recommend finding a namespace that's unlikely to be used by anyone else. ;)
Does your CreateThread use the stdcall calling convention (aka WINAPI)? If you use the cdecl calling convention, it should export the function name as _CreateThread and avoid the linkage conflict with the Win32 CreateThread function.
extern "C" _declspec(export) int _cdecl CreateThread(...
There is no "CreateQtThread" function in Qt, not even something similar. There's a QThread class, and it has constructors. If needed, you can put everything in a namespace.