C++ Dll Export: Decorated/Mangled Names

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 the WINAPI specifier explicitly in the function's definition as the default in Win32 compilers is to use the __cdecl calling convention, also defined as WINAPIV, 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 and my_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



Leave a reply



Submit