Suppose I have a DLL which is built with LARGEADDRESSAWARE linker flag set. Now I have an application dynamically linking to this DLL. Does this make my application LARGEADDRESSAWARE?
If not then, does it make sense to have this flag set for any DLL?
Discussion here seems to indicate /LARGEADDRESSAWARE has no efefct on DLLs and depends totally on the hosting executable.
I believe that the flag must be set on the main executable. So no, it does not make sense to set it on a DLL. (A possible exception might be when the DLL is run using runDll?)
Related
Came across the following paragraph from a page on the MySQL website here:
You can write plugins in C or C++ (or another language that can use C
calling conventions). Plugins are loaded and unloaded dynamically, so
your operating system must support dynamic loading and you must have
compiled the calling application dynamically (not statically). For
server plugins, this means that mysqld must be compiled
dynamically.
What is meant by dynamical compiling? I know about dynamical linking, but I'm not sure what they meant with dynamical compiling.
Also, on Windows 10 (x64), how can I assure that an exe has been compiled dynamically? Is it possible to figure it out from the output of dumpbin? Here's the dumpbin output for mysqld.exe (version 5.7):
Note: I reviewed this old question which did not provide me with that much information. The depends tool it suggests is no longer on Windows.
Compiling dynamically simply means that you are compiling the code such that the compiled output is suitable for dynamic linking.
On Windows, the process of creating as DLL necessarily compiles it such that it's suitable for dynamic linking because DLLs are always dynamically linked.
I believe that most platforms today always compile dynamically and produce relocatable output, even if they're subsequently linked statically.
When one should implicitly or explicitly link to a DLL and what are common practices or pitfalls?
It is fairly rare to explicitly link a DLL. Mostly because it is painful and error prone. You need to write a function pointer declaration for the exported function and get the LoadLibrary + GetProcAddress + FreeLibrary code right. You'd do so only if you need a runtime dependency on a plug-in style DLL or want to select from a set of DLLs based on configuration. Or to deal with versioning, an API function that's only available on later versions of Windows for example. Explicit linking is the default for COM and .NET DLLs.
More background info in this MSDN Library article.
I'm assuming you refer to linking using a .lib vs loading a DLL dynamically using LoadLibrary().
Loading a DLL statically by linking to its .lib is generally safer. The linking stage checks that all the entry points exist in compile time and there is no chance you'll load a DLL that doesn't have the function you're expecting. It is also easier not to have to use GetProcAddress().
So generally you should use dynamic loading only when it is absolutely required.
I agree with other who answered you already (Hans Passant and shoosh). I want add only two things:
1) One common scenario when you have to use LoadLibrary and GetProcAddress is the following: you want use some new API existing in new versions of Windows only, but the API are not critical in your application. So you test with LoadLibrary and GetProcAddress whether the function which you need exist, and use it in the case. What your program do if the functions not exist depend total from your implementation.
2) There are one important options which you not included in your question: delayed loading of DLLs. In this case the operating system will load the DLL when one of its functions is called and not at the application start. It allows to use import libraries (.lib files) in some scenarios where explicitly linking should be used at the first look. Moreover it improve the startup time of the applications and are wide used by Windows itself. So the way is also recommended.
I am compiling a DLL twice (once for x86, once for x64) and I have set /ENTRY to "DllMain". I am using the /MT runtime library option to statically link against the runtime library. This all work fine when doing the x86 build, but the x64 build fails with this:
error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
{project directory}\LIBCMT.lib(crt0.obj)
Why does this work for the x86 build and not the x64 build? Is there something I am missing here?
Not a direct answer but it may be strictly related: as said in the comment, you should avoid changing the entrypoint in that way: normally the real entrypoint is taken by a "fake" DllMain provided by the CRT to initialize its internal data structures (as explained here), so you're bypassing it. Probably the size reduction is due to CRT init code being removed.
Your dll is working with a non-initialized CRT, which is very bad. You should leave the default entrypoint, which, incidentally, should solve your problem.
By the way, notice that actually you could make a dll without the CRT (and it would become really small), but you shouldn't use the CRT at all, without even linking against it (/NODEFAULTLIB switch). This means that you could just use libraries you explicitly link against (e.g. the Windows API), but I suspect you would lose several C++ features (I think at least exceptions and RTTI).
This could be a silly question, but are you sure you're linking as a DLL in the x64 case (ie. specifying the /DLL switch) - since the complaint is about main, I wonder whether it's trying to link as a an executable?
I have an application that uses the winInet classes - #include <afxinet.h> and the wininet.dll
I would like to statically link the WinInet function calls in my application as well as the dll, so I followed these steps. I then copied the wininet.dll into my project directory, as I read here.
Upon building I get the following error - wininet.dll : fatal error LNK1136: invalid or corrupt file
My first question is:
-Am I correctly doing what I think is statically linking function calls and the dll?
-If so, why is the dll corrupt with this setup, but works without these changes?
Any help is appreciated. Thank You.
"Static Linking" is the process of including the code in your application. By nature, a DLL is a dynamic link library and therefore no, including the DLL in the directory of your application is not static linking - it remains dynamic. The reason for placing it in the directory of the application is so that the application can find it without the need for install.
I don't suppose it is the DLL that is "corrupt" - I suspect you are attempting to static link the DLL into the application which cannot happen. You need instead to include the correct .lib file, whatever that is, in the additional libraries to link with and ensure that the lib file you link with is not the DLL exports package for wininet.dll
You shouldn't link directly against the DLL. Instead, link against the corresponding import library (should be Wininet.lib). The DLL still needs to be accessible to your application at runtime, of course. The .lib file is needed by the linker to setup proper linkage to the DLL.
Am I correctly doing what I think is statically linking function calls and the dll?
What you're doing is usually called dynamic linkage (more or less dynamic ..), but its (afaik) the only way to go for Windows System APIs. 'Static' linkage would embed the Wininet code directly into your executable, with no need for an external DLL.
When you link with a DLL, there is a corresponding LIB file to use to set up the correct linkage to the functions. For an example, if you are using a USER32.DLL and KERNEL32.DLL, it's corresponding LIBs that needs to be linked would be USER32.LIB and KERNEL32.LIB.
Sometimes it is not so obvious, you can double check by looking at the MSDN for the function in question, when you scroll down towards the bottom of that page it will tell you what library to link with, for an example, look at the Win32API's CreateProcess, as you look at the bottom of the page, it tells you what is the library to use, in this case it's KERNEL32.LIB.
You just referenced a DLL during the linker phase which the linker could not understand the DLL as it is already a compiled library and hence the linker complained that it was "corrupt".
Change that to WinInet.LIB and all should be ok.
Hope this helps,
Best regards,
Tom.
Which headers should I not use if I don't want my program to be linked with any of msvc*.dll ?
At the moment my application uses:
kernel32
user32
shell32
msvcp90
msvcr90
I want to get rid of the bottom two files. I don't mind if I will have to rewrite certain aspects of the program.
Because I know if you code in C and then link it won't link any msvc's
I believe you have to change the way the CRT is linked into your program. I think for that you have to change the C++->Code Generation->Runtime-Library to the static version. This is for Visual Studio 2005, don't know about newer versions.
Those libraries contain the C++ runtime - heap management and other stuff hard to get rid from.
You could link the C++ statically instead - use "C++ -> Code Generation -> Runtime Library" setting. Then you will not need those .dll files. However this is not the recommended way - if a vulnerability is found in the C++ runtime you'll have to recompile and reship your program.
Static link is the right answer. A related bit of advice is to use depends.exe to see what functions your exe is actually hitting in the dependent dlls. Those dependencies might be due to explicit use on your part or due to CRT implementation that you don't explicitly invoke.