Why some programs require both .lib and .dll to work - dll

When I was going to set up my developing environment for (SDLSimple DirectMediaLayer), I downloaded the package provided by the website, from the readme.txt file I found that I need both .lib and .dll...
My question is :
I am not sure if my understanding is correct : in my thought, .lib for windows is like .a for linux, is static library, and .dll for windows is like .so for linux, is shared library, is this correct ?
If the idea above is correct, I think we can only use .lib or .dll, since the work they do is the same ? So why bother to get both two in one program ?
And I do not quite understand .dll, if my memory servers me right, the one of the advantage for shared library is they can be updated while the program is running, so how can people do this, if we update the .dll file, how can an running program get to know the changes of the .dll and reload it to memory ?

In VC, there are two kinds of libs.
First type is a "real library", generated by the "static library project", which contains everything you can link and run, without dll.
The second type is "import library", generated by the "dll project", which just contains the symbols the link.exe needs. You can link to the library, but you need the dll to run.
There are two ways to use a dll. Link to the "import library" or "use LoadLibrary API".
You can not change the dll file when the dll is loaded.
But if you use LoadLibrary to load the dll, you can use FreeLibrary to unload the dll, change the dll and then use LoadLibrary to load the new dll. Of course, you need to monitor something to invoke this procedure.
Still the easier way is that, use a loader to do the update, then load the real exe.

Related

Dynamically linked DLL is loaded immediately after starting the application

I've dynamically linked libhunspell.dll (HunSpell) to my application. It works, but there is a dumb problem which I don't know why it happens.
Even before I use LoadLibrary("path\\to\\libhunspell.dll"); to load it and use it, on the start of the application it attempts to load the library by itself. If I place the libhunspell.dll into the path where my main executable resides, it can load it, otherwise it reports an error, immediately after starting the application - This application has failed to start because LIBHUNSPELL.DLL was not found. Re-installing the application may fix this problem. and the application doesn't start.
I would understand if the LoadLibrary would use invalid path but this happens as soon as the executable runs, even before the first statement in WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) executes (I've tried to place a breakpoint and it doesn't even reach it, so this happens before).
So, as a result, I must place libhunspell.dll in the same folder as my application executable, and not in the path I want.
This is probably easy to fix although I don't what to look for.
So the question is - how do I avoid it loading it immediately and have it wait until I use LoadLibrary call?
Here is how I linked if it can help:
1) compiled libhunspell.dll in Visual Studio 2015 (I used /MT option to link it statically so it doesn't have VC++ Redistributable as a dependency).
2) created import library (libhunspell.lib) using implib.exe -a -c -f libhunspell.lib libhunspell.dll
3) linked that to the source .cpp unit which is using it using #pragma comment(lib, "libhunspell.lib") (it is RAD Studio 2010 so the .lib is required unlike newer versions).
4) later in the same .cpp used LoadLibrary to load this library and used it.
By linking in the import stubs (libhunspell.lib) the OS will load the DLL for you as it is now a static dependency.
One approach would be specify the library as a delayload dependency: /DELAYLOAD:libhunspell.lib via the linker options. You can then call LoadLibrary on the DLL.
The only other option is to stop including the .lib in the linker step, making it truly a dynamic dependency.
I assume you did Add to project a *.lib file for your DLL. That is a kind of "static" linkage done in the App initialization (prior to your forms are created). So it has two disadvantages.
You DLL must be in the same path as the Apps EXE file
Sometimes DLL file name is locked (can not be changed)
The advantage is that you do not need to do any coding for the DLL loading as the VCL do it for you ... so your app should not contain the LoadLibrary,GetProcAddress calls you just include the *.h file with propper import declarations ...
For dynamic linkage you need to remove the *.lib from your project and use WinAPI LoadLibrary + GetProcAddress for loading your DLL as josh poley suggested. Here an example:
Builder C++ calling VC++ class
Beware there was/(is?) a bug in the GetProcAddress preventing from loading all the functions from your DLL in some cases. Especially if the DLL has old legacy mangling of names the count of functions is high and the DLL was created on compiler incompatible with the mangling in question.

Getting out of DLL Hell with Microsoft.VC90.CRT?

I've built a inproc com server dll which I can package as 1 file or many via the build utility py2exe. When I allow all the dependencies to remain external, I have no issues, but bundling as 1 file produces problems.
When the dll is utilized (either registering it or instantiating a com object from it), it immediately loads MSVCR90.DLL from the path c:\windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6871_none_50944e7cbcb706e5\MSVCR90.DLL no matter what I do, I can't change that. There is no information that I can find (using Dependency Walker) to indicate what is causing that to load. It just happens magically...
Then, later on it loads that dll again via an explicit call to LoadLibraryA("MSVCR90.dll") (part of some py2exe black box?), but this time it does not look into the winsxs manifests / directory. Instead it looks to the system path and/or will respect a dll redirection. That's when the problem occurs. If I set the system path to start with c:\windows\winsxs\x86_microsoft.vc90.crt...\ it will load the exact same dll and be happy - but if ANY other file is utilized - inclusive of a copy of the EXACT same dll - but at a different path - then the whole thing blows up. It can't handle using two different files.
How can I fix this? Ideally, I've love to make the initial magic loading of the dll draw upon a private assembly, but no matter what I do with manifests or .dll.local etc it will not respect that until this second dll loading takes place.
Note that with the non-bundled dll (external dependencies) it always uses the winsxs MSVCR90.DLL.
I can "fix" my failure to use the dll by forcing the system path to load the winsxs copy, but that is pretty useless for a deployable com server!
The reason is that you DLL has a manifest that tells the module loader to search also in the SxS storage.
You have several choices
Build your DLL using static linkage. Not using any of the MFC-DLLs (see project settings)
Don't use a side by side manifest for the DLL and still use the MFC DLLs. But beware you have to ship those DLL with your DLL in the local path (see DLL search sequence docs)
Use a later build of VS. Later versions of VS don't use the SxS storage any more and there are no manifests for those DLLs any more.
For the 2. see this article in code project. There is an update for VS-2008 [here].
2
Build your DLL

How to low-level debug a COM DLL (Firefox plugin) method via C++ code without debug info?

Given the following:
the 32-bit DLL code file of some old Firefox plugin (i.e. a DLL containing among other a Typelib, XSD and XSL entries), without source code or debug info, originally coded in C++ and compiled with Visual Studio,
the name and parameters of an exported function/method in this DLL (a function of the Firefox plugin, accessable in JS code),
Visual Studio Community 2013 running on Windows 7,
experience in C++ development, but not with COM or Firefox,
experience with debugging Intel assembler code,
a code license which does not prohibit disassembling the DLL,
I would like to do this: Load the DLL into some C++ code, and step on CPU level into the code of the function to find out what it exactly does.
Can you give me any hint on where to start and how get this done? I guess the DLL may need some Firefox-specific initialization before I can call the function which I would like to debug. Could this be done with the Firefox SDK, without source code and debug info for the DLL? Or may I succeed in "nakedly" loading the DLL, finding the entry point of the - rather simple - function (how?) and calling it?
Thanks for any hints.
If no pdb file or source code, it is hard for you to debug the dll file, since the debugger loads debugging information from the PDB file and uses it to locate symbols or relate current execution state of a program source code. Visual Studio uses PDB files as its primary file format for debugging information during debugging. If no those files, you couldn't debug that library.
Update:
We are dynamically loading a dll to one project using LoadLibrary() function, but if you want to step into your dll file, it really require the pdb file. A simple sample is that you could create and place one pdb file in the same folder as one simple custom dll library project located. I think Visual Studio will automatically search the directory and load them, you could find the information in your Debug modules windows.
The following case is not the same issue as yours, but it also shared us that it would load the pdb file if the dll file was really called by one project/process:
Does winbase::LoadLibrary() load .pdbs?

Use function of DLL in VBScript

I want to use a function of my Encryption.dll in my VBScript.
If I try to register the dll with regsvr32 /i Encryption.dll I get the error that the dll is loaded, but he can't register the file because there is no DllRegistryServer-Entrypoint.
So I tried another way as I read in a forum:
Set yourClass = CreateObject("Encryption.Hashing")
There I'm getting a ActiveX error.
Anymore ideas of what I can do?
Sounds like maybe the DLL was compiled improperly? Do you have the source? If not, try something like Telerik's JustDecompile and see if it can decompile it. This is not the end all be all kind of test but if it's a .NET dll, you should be able to decompile it. If it's a native DLL, there should be an error.
Without knowing that, there's several reasons you could be having problems.
Try creating a wrapper that exports the functions you need; test it in VS and then build it and try installing it again. Oh, one more thing. Native Libs have a .lib file that usually comes with the DLL if it's meant to be linked to for invoking purposes. That .lib and it's corresponding header files will be what you need to write a wrapper. Cheers.

How to use the .def file for explicit linking?

I am facing the the problem to link to a third party dll. It is windows mobile application, where I am try to link to this third party dll.
Here first I had the dll and lib file. I was not able to link to it explicitly, but implicit linking is working. In the explicit linking the getprocaddress was failing. The dumpbin showed only the dllmain functions being exposed and no other function being exposed, hence the getprocaddress was failing.
However my application doesnot start if the dll is not found/installed in the device. It is expected as it is imlicit linking of a dll hence my application does not start.
I reported this to the third party dll provider and said that I want the explicit linking as the dll takes more space in my application if it is linked implicitly.
They replied by providing the .def file and said that I can use this .def file in my app to explicitly link to a dll.
I don't know how to use this .def file to explicitly link to a dll. Can any one please explain briefly about how to use this .def file in my app to explicitly link to a dll.
Use the *.def file when you build the DLL, to specify what function names the DLL is supposed to export.
After the DLL is built, use dumpbin /exports to verify that the functions are indeed exported from the DLL.
After you have verified that the DLL is exporting functions, you can either link to them at run-time using LoadLibray/GetProcAddress, and/or you can link to them at build-time by passing the DLL's *.lib file (which was created when you built the DLL using its *.def file) as an argument to your application's linker.