C++ Function Calling Assembly Module - c++

I want to write a customized module in assembly and have my C++ functions invoke it. Instead of starting from scratch I would like to write the "draft" in C and let the compiler generates a blue print assembly source i.e.the listing file generated by the /FA compiler option.
However, I found that all the procedure names generated are already in decorated form. Furthermore, the MASM will carry out its own name decoration again. So if I assemble my version without undecorating the compiler generated procedure name manually first I would get a linker error since the function names would not be matching.
Is possible to prevent this type of duplicated name decoration?

Declaring the function extern "C" should result in the generated assembler showing the name you should use in assembler. Just don't forget to make it extern "C" in the header which declares it to C++ later.

You can declare your function as extern "C". That way, it will at most get an underscore before the name:
extern "C"{
void foo(int bla){
}
}
Will become
_foo

Related

Difference extern"C" vs extern

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.

include C declarations with void argument list in C++ program creates compilation error (using gcc version 6.3.0 20170406)

I have always used:
extern "C"{
#include <editline.h>
}
and the editline.h file contains the two following lines:
extern char *readline();
extern void add_history();
In the c++ code I use:
char* mbs=readline((char*)"> ");
and the compiler issues: error: too many arguments to function 'char* readline()'
I understand that in C leaving the argument list empty in the declaration of a function means : "some fixed arguments but undefined".
The code worked in the past, so something should have changed, maybe in the editline.h file or between g++ versions.
What is the correct behaviour regarding the g++ compiler ?
Wrapping declarations in extern "C" doesn't transform them into C code. It just affects name mangling, allowing for linking between the two languages.
The feature you're using doesn't exist in C++, so you can't use it here. C++ simply sees no matching function.
Instead of wrapping entire #include statements in extern "C" and hoping for the best, a C header should be designed to be compatible with C++ callers; such code will typically have extern "C" at appropriate locations in the header itself, and will avoid C-only features like this.
In short, unless you can "fix" the header, you're out of luck.

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);
}

stdcall name mangling using extern c and dllexport vs module definitions (msvc++)

I was trying to export a simple test function for a dll to work with an application (fyi: mIRC) that specifies the calling convention as:
int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
Now, to call this from the application, I'd be using test_func but I have noticed due to name mangling it is not as simple as I'd thought.
Through similar topics here I have come to the understanding that using extern "C" in combination with __declspec(dllexport) is an equivelant (somewhat) method of removing mangling to module definitions (.def). However, when using the extern/dllexport method my function (as an example) is always _test_func#numbers whereas the .def removed all mangling as required for use with the application i needed to export to.
Could someone please explain why this is? I'm just curious about the two methods. Thanks!
extern "C" has nothing to do with stdcall: it only declares that C++ name mangling (aka type-safe linkage; inclusion of type information in symbol name) is disable. You need to use it independent of whether you use C calling convention or stdcall calling convention.
In stdcall calling convention, the callee removes the parameters from the stack. To make that safe, the exported name contains the number of bytes that the callee will remove from the stack.
If the application you are exporting to requires that no #number suffix is added to the name, it probably means that it expects C calling convention. So you should stop declaring the function as __stdcall. When you the declare it as declspec(dllexport), you should get an undecorated name in the DLL.
In the DEF file, you can call the function whatever you want; no additional checking is performed.
dllexport/import are designed to be loaded back by themselves, not an old C library using GetProcAddress. The mangling you have seen is what all Microsoft compilers have done for a long time for __stdcall functions. Most likely, your target either expects a __cdecl function, not __stdcall, but if not, you will need to use a .def file to specifically un-mangle the name.

extern "C" not working as expected

I am trying to hook a Win32 API function. I am making a DLL from which I want to export the function, but I am already failing at the basics. My declaration is as follows:
extern "C" __declspec(dllexport) int WINAPI fnTest(void);
but the exported function name is not "fnTest" - as I would expect - but is "_fnTest#0". I can only make it work when declaring the functions calling convention to __cdecl, which results to an exported name of "fnTest", but since the Win32 calling conection is WINAPI/__stdcall this is not an option.
I am using VS2010. Thanks in advance.
That mangling is part of the __stdcall convention. As the called function has the responsibility to remove the parameters from the stack on return, and removing the wrong amount of data from the stack has disastrous consequences, the number of bytes the parameters take is simply appended to the function name after "#" to let the linker catch potential conflicting definition errors.
Could you explain exactly, how does this pose a problem?
You should use module definition file (.def) instead of __declspec(dllexport).
Just use the following .def file:
EXPORTS
fnTest
If you want to do this you will have to export the functions by ordinal rather than by name using a .DEF file.
stdcall provides a decoration that describes the length of the parameters, in this case #0 since you have no parameters. If you had one parameter it would be #4, and so on.