Why implicit linking to DLL needs a lib file on Windows - dll

On Linux platforms you need only the .so file when you want to implicitly link to it.
Why Microsoft developed the approach where you need a .lib file also. Doesn't the DLL contain all the information for the linker to be able to link to it?
From my experience the "Windows way" is more clumsy and creates problems when you want to mix different compilers and linkers.

Related

How to specify a binary to use some specific dll files?

We are developing audio plugins which are dynamic libraries. This made it very hard to use 3rd-party libraries such as Qt, as our product DLL would search for Qt's DLL on host DAW program's executable directory, and it is impossible to install our dependent DLLs to that position (you don't know which host will be used, and host may even be installed later than the plugin).
I've made some brief search on this problem, the few answers direct me to a Microsoft technology called side-by-side assembly, and I'm almost drawn in the huge documentation and concepts on that. So my question is:
How to make my DLL to load several specific dependent DLLs located at path_to_plugin/MyPlugin_dependents/xxx.dll?
Or is there any examples to side-by-side assembly that simply do this and is much simpler than the official example?

How to create Cygwin compatible library files from native Windows .dll and/or .lib files

I have downloaded both a .dll and a .lib file compatible for 32-bit Windows from libspotify. The project I am working on requires me to use other libraries that does not work on Windows, but compile and work using Cygwin. I therefore need a way to get the .dll and/or .lib file "converted" into a compatible Cygwin format. Is that possible?
The .dll file does not contain symbols, so the suggested method described in the bottom of the Cygwin doc did not work.
The other libraries that I have, generated the following files:
/usr/local/lib/{libname.la, libname.dll.a and sometimes libname.a}
/usr/local/bin/cyglibname.dll
Where libname is the name of the library correctly compiled and installed. How do I get these files from the native 32-bit Windows .dll and .lib files?
Update:
I tried to include the full path to the .dll file instead of using -l and -L as I am used to linking libraries, and I got the following message:
/usr/bin/ld: i386 architecture of input file `/usr/local/test/libspotify.dll' is
incompatible with i386:x86-64 output
It seems like the problem is the 32-bit vs 64-bit. Anyone know how to fix that?
Another update:
It worked by adding -m32 to CFLAGS and LDFLAGS. I now got a different error that I believe is irrelevant for the original question.
It seems like the problem is the 32-bit vs 64-bit. Anyone know how to fix that?
Yes; use 32 bit Cygwin for a project that depends on third party DLL's only available in 32 bit form. Do not use 64 bit Cygwin.
Cygwin and Cygwin-64 can be installed side by side, by the way. (And it's possible to share the same home folder between them, so you don't have to duplicate your .bashrc and whatnot.)
This is not a Cygwin problem. If you build a 64 bit executable with, say, Microsoft Visual Studio, it also will not load the 32 bit libspotify DLL.

Win32 Project (API): Compatibility with other version of Windows

I use API to make a programs. It runs pretty well on Windows 7 (with debug file .exe), but it doesn't when I run it on Windows XP. Are there any ways to solve this problem?
I suppose you are using Visual C++, according the the message you get.
Your project is set up (by default) to link the Microsoft C++ Runtime Librairy dynamically, so it saves up space in your final executable, but you need the dynamic linked libraries to be in your system or in your executable's folder.
To solve this in Visual C++, without any afford from who are executing the program in their machines, you can change how MSVC link their runtime library to your executable, that is, if you set it to be linked statically, all the dependencies will be linked inside your final .exe, with no need of additional .dlls.
To change this option, refer to /MD, /MT, /LD (Use Run-Time Library) - MSDN.
Or in short: Project Properties>Configuration Properties>C/C++>Code Generation>Runtime Library
If in debug mode, use /MTd, otherwise use /MT.

LoadLibrary MSVCRT Issue

There are two questions that confuse me:
I read from the Microsoft website that we can not use different C runtime in the same project. Say I have a dll compiled with /MT flag, then I can not use the dll in a /MD compiled project. My question is that if I use LoadLibrary() to load the dll, is it also necessary that I have the same C Runtime? What's the potential danger if I don't?
I think with the /MT flag, the runtime is statically linked into the binary file. But for one of my dll project, I made a dll with /MT. However, when I dumpbin.exe /dependents mydll, it shows that MSVCR100.dll is a dependent. My question is that why the dll is still dependent on MSVCR100.dll?
1) No, that's not a requirement. This happens in any program, the Windows DLLs use their own CRT for example. Mixing CRTs in one program is however very dangerous and can cause very hard to diagnose problems. The Windows apis were carefully designed to avoid those problems, they never require code to release memory that was allocated in a DLL, don't use exceptions, don't use standard C++ library classes, don't depend on locale or any other kind of shared CRT state. The kind of things that go wrong when you mix. Restricting yourself to a C or COM api helps a lot to avoid these traps.
2) This will happen when you link code that was compiled with /MD. Common with .libs you link.
You stay out of trouble by always using /MD when you have DLLs in your project and compiling all code with the exact same compiler and options. Static libraries you didn't build yourself are very troublesome, avoid them.
Regarding your 2. question, the dependency is indirect. Your DLL uses a DLL which depends on MSVCR100.dll. Using Dependency walker you can see the dependency tree of your component and see which library is directly and indirectly dependent.

JNA try to Access native DLL and get module not found error, Dependencies are missing

I have Visual Studio 2010 installed and have a project I got from someone else which I can build successfully without any errors. I get a Wrapper.dll,
which I would like to access using JNA.
I am using Win7 64-bit.
But I get the error: java.lang.UnsatisfiedLinkError: Unable to load library 'Wrapper': The specified module could not be found.
Wrapper.dll of course is in the correct folder and it is a 32-bit dll and my Java program also uses a JRE with 32-bit, so this is not the cause of the error.
I used DependencyWalker to check whether *.dlls are missing:
MSVCP80.DLL
MSVCR80.DLL
GPSVC.DLL
IESHIMS.DLL
And yes there are some missing.
Can I conclude that the error is related with that these DLLs are missing?
But why does Visual Studio compile correctly then and does not throw an error?
How to solve this in order to access these functions in Wrapper.dll?
I also read that downloading dll's might not be the right thing to do!
(I know that Wrapper.dll relies on another dll or sourcecode which was built in Visual Studio 2005, if that is of interest.)
EDIT:
I found out, that Wrapper.dll relies on three other dlls which probably were built on MSVS2005. These require the above mentioned DLL's (checked with dependencywalker) and I guess therefore Wrapper.dll also links them.
So what do I actually do to get rid of these old dll's?
Would I need to build the other three DLLs with VS2010 or
is this a problem which always will appear, meaning, that you need to copy paste old DLLs in order to use the precompiled Libraries which are dependent on those.
Is there a way, that the program would run on any other system as well without copy pasting these DLL's?
All required DLLs must be available to the system for loading. If you define jna.library.path, that is where JNA will look for the initially loaded DLL, as well as any dependent DLLs. In addition, java.library.path (which is essentially PATH) will be searched for dependent DLLs.
MSVS often uses paths in addition to PATH when building, debugging, and running code within that environment.
Solutions:
a) remove dependencies you don't really need; this may include telling MSVS to build your DLL differently
b) include non-system DLLs next to your custom DLL (or include their location in PATH/java.library.path)
EDIT
a) you can include the offending DLLs in the same directory as yours. this is fairly low impact on the target system, but if they are DLLs that are expected to be on any system, you shouldn't have to do so. It's preferable to adjust java.library.path so that all system DLLs are accessible.
b) you can recompile your dependent DLLs and be more careful about backward compatibility and explicit linkage. Depending on features used by the DLLs, though, you may not be able to remove the dependencies.
MSVC[RP]80.DLL are C and C++ runtimes, respectively; you may or may not be able to link against a previous version.
IESHIMS.DLL is part of IE and should be on the system, but likely in a path inaccessible to your program.
GPSVC.DLL has to do with group security policy, so it should be available on the system (modulo whenever the DLL was introduced).