How do I stop name-mangling of my DLL's exported function?
Small correction - for success resolving name by clinet
extern "C"
must be as on export side as on import.
extern "C" will reduce name of proc to: "_GetName".
More over you can force any name with help of section EXPORTS in .def file
C++ DLL Export: Decorated/Mangled names
You can get what you want by turning off debug info generation. Project + Properties, Linker, Debugging, Generate Debug Info = No.
Naturally, you only want to do this for the Release build. Where the option is already set that way.
c++ dll export mangled name
You must decorate both declaration and definition of a function with extern "C" __declspec(...)
otherwise you should be getting a warning about non consistent linking definition and erratic behaviour.
DLL export __stdcall without DEF file and decorated function names with VS
The standard approach to this problem is to define your export's undecorated name in a .def
file - and this is the approach you should use.
But if for whatever reason you don't want to use a .def
file, you can write code like:
__declspec(dllexport) int __stdcall TestFunktion(void)
{
#pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
...
}
__FUNCDNAME__
will evaluate to your decorated function name, while __FUNCTION__
will evaluate to your undecorated function name - this is effectively a replacement for the equivalent line in the .def
file.
As for your other question:
If I have a DLL file...how can I see functions are built as __stdcall or __cdecl?
this is not strictly possible from the DLL alone, much less if you deliberately omit hints from the export table (i.e. you might be able to see a decorated export symbol and infer that it's __stdcall
, but you're choosing to export them as undecorated symbols) - perhaps if you perform some sort of analysis on the function's disassembly and try to understand its calling convention, but this is non-hermetic and very hacky.
This is why well-documented calling conventions and well-documented API signatures are important.
Correct calling convention for exporting windows DLL functions for Excel VBA without mangled names
Per Microsoft's documentation:
https://docs.microsoft.com/en-us/office/client-developer/excel/developing-dlls
When compilers compile source code, in general, they change the names of the functions from their appearance in the source code. They usually do this by adding to the beginning and/or end of the name, in a process known as name decoration. You need to make sure that the function is exported with a name that is recognizable to the application loading the DLL. This can mean telling the linker to associate the decorated name with a simpler export name. The export name can be the name as it originally appeared in the source code, or something else.
The way the name is decorated depends on the language and how the compiler is instructed to make the function available, that is, the calling convention. The standard inter-process calling convention for Windows used by DLLs is known as the WinAPI convention. It is defined in Windows header files as
WINAPI
, which is in turn defined using the Win32 declarator__stdcall
.A DLL-export function for use with Excel (whether it is a worksheet function, macro-sheet equivalent function, or user-defined command) should always use the
WINAPI
/__stdcall
calling convention. It is necessary to include theWINAPI
specifier explicitly in the function's definition as the default in Win32 compilers is to use the__cdecl
calling convention, also defined asWINAPIV
, if none is specified.You can tell the linker that a function is to be exported, and the name it is to be known by externally in one of several ways:
- Place the function in a DEF file after the
EXPORTS
keyword, and set your DLL project setting to reference this file when linking.- Use the
__declspec(dllexport)
declarator in the function's definition.- Use a
#pragma
preprocessor directive to send a message to the linker.Although your project can use all three methods and your compiler and linker support them, you should not try to export one function in more than one of these ways. For example, suppose that a DLL contains two source code modules, one C and one C++, which contain two functions to be exported,
my_C_export
andmy_Cpp_export
respectively. For simplicity, suppose that each function takes a single double-precision numerical argument and returns the same data type. The alternatives for exporting each function by using each of these methods are outlined in the following sections....
The article then goes on to provides examples of each method.
In your case, since you are already doing the 2nd method and not getting the result you want, you will have to employ the 1st or 3rd method as well.
Can I change mangled C++ DLL export symbols? (Binary-compatible but Source-incompatible)
It is fine, they are binary compatible.
The only wall you could run into is the name mangling of the exported function. If the DLLs that you cannot change exported these functions using their decorated C++ name then you'll get a fail whale at runtime when the client cannot find the exported name. This will happen when the programmer didn't use extern "C"
or didn't use a .def file to rename the exports. Otherwise easy to see with Dumpbin.exe /exports. Fixing that is painful, you'll need to modify the DLL header to change wchar_t to WORD, a macro can do that, and write little adapter functions that take wchar_t and calls the WORD function by casting.
If these are exported C++ classes then you have a bigger problem. You'll need to create a new import library for these DLLs. Start with the output you get from Dumpbin.exe /exports, giving you the original names. And create a .def file from that, using its foo = bar option to rename a symbol. Create the import library with the lib.exe /def option. Create a little test DLL to figure out exactly how you should rename the mangled name.
why the @number symbol at the end of an exported dll function
The "@n" is used by the stdcall
calling convention. You don't need to mention it in your declaration, you just need to change your declaration to stdcall
so that the compiler knows they need to be decorated with "@n" suffixes. Like this:
__declspec ( dllexport ) XLStatus __stdcall _xlActivateChannel(XLportHandle, XLuint64, unsigned int, unsigned int)
Related Topics
The Benefits/Disadvantages of Unity Builds
How to Initialise Memory With New Operator in C++
Why Doesn't a Derived Template Class Have Access to a Base Template Class' Identifiers
C++0X Lambda Capture by Value Always Const
"Constructing" a Trivially-Copyable Object With Memcpy
Vector of Vectors to Create Matrix
C++ How to Determine Whether a Pointer Points to a Valid Object
Calculating Normals in a Triangle Mesh
Passing a String Literal as a Type Argument to a Class Template
Converting a Pointer into an Integer
Static_Assert Dependent on Non-Type Template Parameter (Different Behavior on Gcc and Clang)
Throw Keyword in Function'S Signature
Is Sizeof in C++ Evaluated At Compilation Time or Run Time
What Does "Default" Mean After a Class' Function Declaration
Why Class Data Members Can't Be Initialized by Direct Initialization Syntax
Pinpointing "Conditional Jump or Move Depends on Uninitialized Value(S)" Valgrind Message