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.
Related
I have a DLL and I want to call a function in it. I check the DLL using Dependency Walker and the result I got is:
void U2U_Test(void)
This is the code that I wrote, but GetProcAddress() returns NULL:
typedef void(*U2U_Test_pointer)();
void check() {
HINSTANCE hGetProcIDDLL1 = LoadLibrary(_T("my_dll.dll"));
if (hGetProcIDDLL1 == NULL)
return;
U2U_Test_pointer addr = (U2U_Test_pointer)GetProcAddress(hGetProcIDDLL1, "U2U_Test");
if (addr == NULL)
return;
return addr();
}
Depending on conventions and compiler used, the actual name exported in the DLL might not be exactly the same as the one you wrote in your source code.
This phenomenon is commonly called name decoration or name mangling.
In fact you are guaranteed to have exactly the same name only if
Your compiler conforms to C conventions (probably it does)
The function is exported in C and not C++. Use extern "C" to specify it.
The calling convention is _cdecl (specify __cdecl in function declaration)
For example, when call convention is __stdcall instead of __cdecl, which is common for many windows DLLs (they often write WINAPI or CALLBACK instead of __sstdcall), the name of the exported function is often suffixed by #n where n is the number of bytes expected on the stack for parameters.
In your case, it could be U2U_Test#0.
Indications like __declspec(dllimport) and __declspec(dllexport) tell the compiler to automatically take care of that kind of thing when DLLs are imported/linked at compile time.
IN C++, complex name decoration is used in order to support methods, function overloading, templates and other features, and each compiler invented crazy naming schemes to make sure there won't ever be any clash.
Because at DLL level, there's no template, no classes, only a list of exported symbols indexed by their name or an ID.
That's the reason why most DLLs are exported in C and why most header files declare functions coming from DLL inside a extern "C" { ... } block.
I'm having trouble with loading a DLL in my assignment project.
Here's the header file:
I have omitted code that works and is irrelevant to the problem. Basically, hinstLib is not NULL but when the line Filter = (FILTPTR) GetProcAddress(hinstLib, "Filter"); is executed, Filter has no value. To me it seems like it is saying that the DLL has been found but it cannot find the function "Filter" inside the DLL and I have no idea why, albeit I could be wrong. I still haven't got my head around how some of this works.
Here is the DLL:
Any ideas anyone? All help is greatly appreciated!
James
Your specifiers are wrong.
A good, concise way do to this is to use same header to in DLL and APP, defining the export-import interface., which uses macro like this:
#ifdef MY_DLL_EXPORTS
#define MY_DLL_API __declspec(dllexport)
#else
#define MY_DLL_API __declspec(dllimport)
#endif
And declarations:
extern "C" MY_DLL_API int Filter(int* data, int count, const WCHAR* parameterString);
Library's .cpp file would use this header and would define MY_DLL_EXPORTS.
If I understand your code right, you made it so that linker tries to export same function from both modules? ALso, function's prototype should be C-compatible to be actually extern "C"
when the line Filter = (FILTPTR) GetProcAddress(hinstLib, "Filter"); is executed, Filter has no value. To me it seems like it is saying that the DLL has been found but it cannot find the function "Filter" inside the DLL and I have no idea why
The function is likely being exported with a decorated name. You are not specifying a calling convention, so the default is usually __cdecl, which prefixes the function name with an underscore, thus it would be exported as "_Filter" instead. But this is compiler-specific behavior, so double-check your DLL's EXPORTS table with a PE viewer/dumper to see the actual name being exported. You may need to add a .def file to your project to ensure the function is exported as "Filter" as desired.
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
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.
I'm writing a C/C++ DLL and want to export certain functions which I've done before using a .def file like this
LIBRARY "MyLib"
EXPORTS
Foo
Bar
with the code defined as this, for example:
int Foo(int a);
void Bar(int foo);
However, what if I want to declare an overloaded method of Foo() like:
int Foo(int a, int b);
As the def file only has the function name and not the full prototype I can't see how it would handle the overloaded functions. Do you just use the one entry and then specify which overloaded version you want when passing in the properly prototyped function pointer to LoadLibrary() ?
Edit: To be clear, this is on Windows using Visual Studio 2005
Edit: Marked the non-def (__declspec) method as the answer...I know this doesn't actually solve the problem using def files as I wanted, but it seems that there is likely no (official) solution using def files. Will leave the question open, however, in case someone knows something we don't have overloaded functions and def files.
Function overloading is a C++ feature that relies on name mangling (the cryptic function names in the linker error messages).
By writing the mangled names into the def file, I can get my test project to link and run:
LIBRARY "TestDLL"
EXPORTS
?Foo##YAXH#Z
?Foo##YAXHH#Z
seems to work for
void Foo( int x );
void Foo( int x, int y );
So copy the C++ function names from the error message and write them into your def file. However, the real question is: Why do you want to use a def file and not go with __declspec(dllexport) ?
The mangled names are non-portable, I tested with VC++ 2008.
In the code itself, mark the functions you want to export using __declspec(dllexport). For example:
#define DllExport __declspec(dllexport)
int DllExport Foo( int a ) {
// implementation
}
int DllExport Foo( int a, int b ) {
// implementation
}
If you do this, you do not need to list the functions in the .def file.
Alternatively, you may be able to use a default parameter value, like:
int Foo( int a, int b = -1 )
This assumes that there exists a value for b that you can use to indicate that it is unused. If -1 is a legal value for b, or if there isn't or shouldn't be a default, this won't work.
Edit (Adam Haile): Corrected to use __declspec as __dllspec was not correct so I could mark this as the official answer...it was close enough.
Edit (Graeme): Oops - thanks for correcting my typo!
I had a similar issue so I wanted to post on this as well.
Usually using
extern "C" __declspec(dllexport) void Foo();
to export a function name is fine.
It will usually export the name
unmangled without the need for a
.def file. There are, however, some
exceptions like __stdcall functions
and overloaded function names.
If you declare a function to use the
__stdcall convention (as is done for many API functions) then
extern "C" __declspec(dllexport) void __stdcall Foo();
will export a mangled name like
_Foo#4. In this case you may need to explicitly map the exported name
to an internal mangled name.
A. How to export an unmangled name. In a .def file add
----
EXPORTS
; Explicit exports can go here
Foo
-----
This will try to find a "best match" for an internal function Foo and export it. In the case above where there is only
one foo this will create the mapping
Foo = _Foo#4
as can be see via dumpbin /EXPORTS
If you have overloaded a function name then you may need to explicitly say which function you want in the .def file
by specifying a mangled name using the entryname[=internalname] syntax. e.g.
----
EXPORTS
; Explicit exports can go here
Foo=_Foo#4
-----
B. An alternative to .def files is that you can export names "in place" using a #pragma.
#pragma comment(linker, "/export:Foo=_Foo#4")
C. A third alternative is to declare just one version of Foo as extern "C" to be exported unmangled. See here for details.
There is no official way of doing what you want, because the dll interface is a C api.
The compiler itself uses mangled names as a workaround, so you should use name mangling when you don't want to change too much in your code.
There isn't a language or version agnostic way of exporting an overloaded function since the mangling convention can change with each release of the compiler.
This is one reason why most WinXX functions have funny names like *Ex or *2.
Systax for EXPORTS definition is:
entryname[=internalname] [#ordinal [NONAME]] [PRIVATE] [DATA]
entryname is the function or variable name that you want to export. This is required. If the name you export is different from the name in the DLL, specify the export's name in the DLL with internalname.
For example, if your DLL exports a function, func1() and you want it to be used as func2(), you would specify:
EXPORTS
func2=func1
Just see the mangled names (using Dependency walker) and specify your own functions name.
Source: http://msdn.microsoft.com/en-us/library/hyx1zcd3(v=vs.71).aspx
Edit: This works for dynamic DLLs, where we need to use GetProcAddress() to explicitly fetch a functions in Dll.