I am trying to link against a dll, which is accompanied by a header file. Since there were no *.lib file available, I made one by manually creating a *.def file (Ref)
Now the problem is, my test program is __cdecl and the methods in the dll are __stdcall.
Is there a way to force __stdcall for specific methods when they are dynamically linked?
Even though its not an option, tried changing the calling convention (/Gd) to /Gz, but the name mangling came up saying the linker failed to find the slightly mangled method as shown below.
LNK2019 unresolved external symbol _TSTInitialize#24 referenced in function
The function signature in header file is,
#define TSTPERC_API /*__declspec( dllimport ) __stdcall */
TSTHandle cOpts;
//call native methods
TSTFunctionResult cResult = ::TSTInitialize(
p_strPathToLib.c_str(), p_strConfigStruct.c_str(), p_strLic.c_str(),
p_strRFU1.c_str(), p_strRFU2.c_str(), &cOpts );
Well, you don't force stdcall on methods with incorrect .def or incorrect .lib files.
The #24 in this case is the bytes on the stack the callee needs to cleanup. So there is no way around stripping it off (in case you do, then there is no way for the callee to know how many bytes to cleanup from the stack!! ).
The real problem was with the *.def file I created. The syntax is the other way around in my comment to #hans-passant,
TSTInitialize#24=TSTInitialize
This will make the correct export symbol, _TSTInitialize#24 in the lib file linker is looking for. This helps reverting the program to use /Gd instead of /Gz
Related
I'm working in Visual C++, VS2015 Community. I've written this tiny little DLL:
#include "stdafx.h"
int showMsgBox(wchar_t* caption, wchar_t* message)
{
MessageBox(NULL, message, caption, 0);
return 0;
}
And this tiny little client:
#include "stdafx.h"
__declspec(dllimport) int showMsgBox(wchar_t* caption, wchar_t* message);
int main()
{
showMsgBox(L"SimpleDLLClient", L"Hello DLL World!");
return 0;
}
To export the showMsgBox function, I've created this module definition file:
LIBRARY SimpleDLL
EXPORTS
showMsgBox
When I link my client, I pass it the import library that was created when I linked my DLL. Everything compiles and links fine.
And that puzzles me.
According to MSDN, "Because the Visual C++ compiler uses name decoration for C++ functions, you must either use the decorated name as the entryname or internalname, or define the exported functions by using extern "C" in the source code."
But I'm not exporting a decorated name, am I?
If, instead of using a module definition file, I were to prefix the function with the __declspec(dllexport) extended attribute, I wouldn't be surprised (as this ought to have whatever name decoration the compiler applies match the same decoration applied by the compiler to the client).
Likewise, if I prefixed the function with 'extern "C"' in both the DLL and client code, that should also work (and it does: I tested it), because, again, the symbols should match.
But, I would have expected an undecorated export in the module definition file to fail to resolve the client's reference to the same undecorated name, when neither the DLL nor client code uses 'extern "C",' which seems also to be what MSDN says I should expect. Yet, exporting the undecorated name via the module definition file does work, even when I do not use 'extern "C"' anywhere.
Can anyone tell me why this works?
UPDATE
Looking into the files created by the linker, I see that putting the undecorated name into the module definition file apparently results in the decorated name being included in the import library. When I use dumpbin /exports on that file, here's what I get:
File Type: LIBRARY
Exports
ordinal name
?showMsgBox##YAHPEA_W0#Z (int __cdecl showMsgBox(wchar_t *,wchar_t *))
Now, somewhat amazingly (to me, anyway), if I explicitly alias the decorated name, like this:
LIBRARY SimpleDLL
EXPORTS
showMsgBox=?showMsgBox##YAHPEA_W0#Z
dumpbin tells me that this is what shows up in the import library:
File Type: LIBRARY
Exports
ordinal name
showMsgBox
Using that as input to the linker when I build the client works fine too, provided that I use 'extern "C"' when I declare my imported function:
extern "C" int showMsgBox(wchar_t* caption, wchar_t* message);
That makes sense, since the symbol the linker is now looking for is the undecorated "showMsgBox," and I have aliased that symbol to the decorated name created when I compiled my DLL.
Soooo...
What it looks like to me is that pages and pages of MSDN documentation that all say you must use decorated names in module definitions files are mistaken. Rather, it appears that if you use the undecorated name in your module definition file, it is the decorated name that is actually incorporated into your import library, which will resolve the reference to the matching decorated name constructed when you compile your client code. That, of course, is what I would prefer, rather than having to extract the decorated names and use those in my module definition files. It just doesn't match what the MSDN pages repeatedly say.
I like to think I'm a bright boy, but it's pretty arrogant of anyone to suggest that Microsoft doesn't know how its own products work.
What am I missing here?
UPDATE 2
With the DLL and client both using decorated names (that is, no use of 'extern "C"' anywhere), everything builds fine with the undecorated name in the module defintion file, like I said. But, interestingly, with no changes at all to the source code, things build equally well if I do use the decorated name in the module definition file:
LIBRARY SimpleDLL
EXPORTS
?showMsgBox##YAHPEA_W0#Z
At the binary level, the import library this creates is nearly identical to the library created when I use the undecorated name in the module definition file. The only differences appear to be time-stamps, with the exception of one byte near the end. Still trying to make sense of that one, but it appears ever more certain that, somehow, the linker is exporting the decorated name, even when the module definition file refers solely to the undecorated name.
I am playing with DLLs to get a better understanding of them. So I created a simple dll (with load-time dynamic linking) which has functions to Add, Sub and Mul. In the header file for the dll I used __declspec(dllexport) for the function declaration.
For the executable, I added the .lib created after compiling the dll to the properties (for linking). After that I directly called the function Add without using __declspec(dllimport). The program worked. I then changed the function calling to __declspec(dllimport) (Add) and the program worked again.
I am not able to understand what the need of __declspec(dllimport) is? I have not yet coded a run-time linking DLL but from the examples I have seen, dllimport is not needed in that case as well.
Thanks for your assistance.
I have two existing executables A and T, in the same solution that both ran just fine before I touched them. In executable A is a header defining a class P, and a prototype for a static instance MyP. The definitions are compiled in project A. In executable T, I wanted to call member functions of MyP in project A, so I added dllimport/export macros to the declarations of the class and MyP in the headers (not at the definitions), and included the headers in project T. The dllimport/export macros are standard, and A_EXPORTS is defined in project A, but not in T.
#ifdef A_EXPORTS
#define A_API __declspec(dllexport)
#else
#define A_API __declspec(dllimport)
#endif
//various definitions and includes, defining ENUM_RECORDING_TYPE and ERROR
A_API HFILE viosopen(const _TCHAR *path, ENUM_RECORDING_TYPE rt, int flags);
A_API struct P {
ERROR B(SHORT phraseNum);
};
A_API extern P MyP;
I added project A as a dependency on project T in the solution. A still compiles fine, but T comes up with unresolved external symbol "__declspec(import) <snip> referenced in function <snip> for the function calls, and unresolved external symbol "__declspec(dllimport) class P MyP" <snip> for the static object. I also see in the output log, right after it starts linking: Creating library Debug/A.lib and object Debug/A.exp which seems ominous since it's supposed to be linking against the existing executable.
My question is: how can I tell MSVC 2010 where those are? I thought simply setting A as a dependency would have it figure that out automatically. I can link against the existing executable, right?
To statically link your program you don't need the __declspec() stuff and you don't need a separate project to create a LIB file. I think you can just link using the .obj file from your A project.
Your A project has a header file and presumably has a .cpp file that contains the implementation of the items described in that header. Let's say your header file is foo.h and the associated implementation is foo.cpp. When compiled, there should be a foo.obj intermediate file in the <solutiondir>\A\Debug or <solutiondir>\A\release intermediate folder. That file can be used by the linker.
In project T's properties, find Linker | Input and change the "Additional Dependencies" property to include the foo.obj file. One approach would be to use a relative file path to locate the file - for example ..\A\Debug\foo.obj in your debug configuration. Another approach is to use the simple file name in "Additional Dependencies" - foo.obj - and then use Linker | General | Additional Library Directories" to help the linker find the file - e.g., ..\A\$(IntDir). Using the $(IntDir) macro has the advantage that the same value works for Debug and Release settings.
Remember to set up a build dependency from your T project to your A project to be sure the A project is compiled first. Otherwise the foo.obj file might not exist when the T linker comes to look for it. In the Solution properties, select Project Dependencies and then set Project T depends on Project A.
To dynamically link you need to use the A.LIB file as #ajay said. The __declspec(DllImport) tells the compiler what functions and data you are importing but doesn't tell it where you are importing those things from.
Using the A.LIB file as input to the linker is much the same as using the foo.obj file in the statically linking case except that the lib file ends up in the solution output directory <solutiondir>\Debug instead of the project intermediate directory <solutiondir>\A\Debug.
This walkthrough on creating and using a DLL might be useful background.
I asssume project A is DLL not an EXE, which is successfully producing a LIB file.
You need to use the A.LIB as Linker Input in project B. Just producing LIB file wont make other projects automatically link to it.
Module-definition (.def) files provide
the linker with information about
exports, attributes, and other
information about the program to be
linked. A .def file is most useful
when building a DLL. Because there are
linker options that can be used
instead of module-definition
statements, .def files are generally
not necessary. You can also use
__declspec(dllexport) as a way to specify exported functions.
http://msdn.microsoft.com/en-us/library/28d6s79h%28VS.80%29.aspx
I was wondering, should we prefer .def way? or dllexport way?
Module-definition (.def) files provide us with more flexibility to define how data going to be exported.
For example, function exported can be anonymous (identified by ordinal) which prevent people without the declaration information from using it.
It can also ddo function forwarding/redirection as stated below :
http://msdn.microsoft.com/en-us/library/hyx1zcd3(v=VS.80).aspx
If you plan on users using your DLL in Visual Basic (not VB.NET), then you may want to opt for using the .DEF file. Visual Basic requires that functions use the stdcall calling convention, and exported stdcall function names are decorated with underscores (_). You can override this function name decoration by explicitly specifying the function name in the .DEF file.
For more information: http://msdn.microsoft.com/en-us/library/dt232c9t%28VS.90%29.aspx
I have a programme I which I want to implement button class. I have declared all my variable in button.h and defined all methods in button.cpp and I am calling these functions in WINMAIN the following error appears.
keylogger.obj : error LNK2005: "struct HBITMAP__ * hOldBmp" (?hOldBmp##3PAUHBITMAP__##A) already defined in Button.obj
The error is for multiple defination hOldBmp but It is only defined in button.h
"Only defined in button.h" is exactly your problem. Unless you declared it as extern there and put the definition into a C++ source file (not header file), every translation unit will get their own definition of the variable.
Seems like a common error: you include the implementation of this hOldBmp pointer from two .obj files, so from two cpp files. So both obj files contain code to implement this pointer. The linker cannot decide which implementation to use in the final binary.
Solution: leave only the declaration in the header file. You may declare it extern or make it a static member variable of the button class. Put the definition in the cpp file.