Why does curl require both .lib and .dll to work? - c

I just downloaded curl and managed to build a programe with it.
What I don't understand is why it requires both curllib.lib and curllib.dll ?
In my opinion either curllib.lib or curllib.dll should be enough, why both?
Also I've searched through the source but doesn't find anywhere it uses dlopen to load curllib.dll, so why is curllib.dll required to run?

curllib.lib is the import library. It contains stubs for all the functions whose actual code is in the DLL, and it contains code to load the DLL. The .lib is automatically generated by the build system (e.g. Visual Studio), which is why you won't find any references in the code. You will find, however, some directives that tell the compiler/linker to export certain functions:
__declspec(dllexport) on a function declaration will export that function. This is convenient, but Microsoft-specific. For example:
void __declspec(dllexport) foobar(int qux);
More information here.
Alternatively, a .def file can be used, that explicitly lists all functions that are exported. For example:
LIBRARY MYFOO
EXPORTS
foobar #1
More information here.
You can do without the .lib if you really want to, but you'll have to manually use LoadLibrary, GetProcAddress and friends to call the function in the DLL.

The .dll is required to run. The .lib exists so the linker can resolve the ordinals and addresses from function names, and is only required at link time.
Other systems (such as Linux) maintain full linkage information in shared libraries and would not require this.

When you use a DLL on Windows, you typically use it with a .lib file that tells the linker enough to be able to create an executable. The executable then uses the .dll file at run time.
OTOH, dlopen is a UNIX/Linux/POSIX kind of thing -- the equivalent on Windows would be LoadLibrary. You'd normally use dlopen with a .so file.

Related

Can we link a dynamic C library statically?

We know that when linking a static library, the linker copies the relevant code from .a file to the executable binary file. And when linking a dynamic library, the linker just copies the addresses of functions it found in .lib file (under Windows) into the binary file, and the functions themselves are not copied. At runtime, the OS loads the dll, and the program runs the code according to the addresses. The question is, could I use the .lib file and dll to link the dynamic library statically? The linker reads addresses from the .lib, and then copies relevant code from the dll to binary file. It should work, right?
I have no clue whether your idea could work, but do note that -- on Windows, with Visual Studio at least -- a static library is something very different from a DLL.
With VS, a static library is basically just an object file container, that is, you have a .lib file, but that .lib file is just a container for all the .obj files that the compiler produced for the project.
The important thing here is that the .objcode in the static library hasn't gone through the linking stage yet, no linker has been involved.
Whereas the DLL is (finally) produced by the linker (from object files).
So the question here is really one of toolchain support, since the DLL is already a linker output, I doubt you could get the linker to re-link its PE code directly into the executable.
If you want to link the .dll at build time instead of run time yes, it can be done using the .lib file that corresponds to the .dll. The exact method depends on what you are using to build your application.
In Visual Studio you start by adding the .lib file in Linker->Input on the project properties.
While this is static linking it does not copy the .dll code into your executable; you still need the .dll to run the application.
Additionally, if the .dll is something you developed and/or have the source code, it can be modified/rebuild as a static library and linked into your executable (so you will not have a separate .dll file).

How does Windows API work?

It seems we are free to use Windows API simply by including header files needed. However, i couldn't make myself understand how this is possible given that header files do not have function definitions but declarations, which is supposed to be considered as an error in that it lacks implementation details. In what way does a compiler locate an implementation detail and map it into memory?
The Windows API is implemented in DLLs that are installed when you install Windows. Those DLLs are in the System directory and have names like User32.dll, Kernel32.dll, etc.
As you correctly noted, the Windows API header files supplied with your compiler contain only the declarations. When your C program calls one of those functions (or any other function that's identified in a header file but not actually compiled with your project), the compiler places a record in the generated object file that says, in effect, "I need to call a function called GetWindowRect (or whatever the name of the function you called)."
The linker is what actually resolves the names. If you look at your linker options, you'll see that it's linking some libraries like User32.lib, Kernel32.lib, etc. Those libraries contain compiled functions that are little more than stubs--code that causes the corresponding DLL to be loaded, and then calls the function in the DLL.
It's a little bit more involved than that, but that's the general idea. In summary:
You include the Windows API header files.
Your code makes a call to one or more Windows API functions that are declared in those header files.
The compiler makes a note for the linker to resolve those API function calls.
The linker resolves the calls by finding the stub functions in the libraries that you specify on the linker command line.
At runtime, a call to one of those functions causes the corresponding DLL to be loaded, and then control is branched to the function in the DLL.
It works the same as any other library, for example C stdlib - your program only needs to 'know' the prototypes of functions (and thus the underlying symbol names). After compilation comes linking - that's when the symbols (function definitions) that are missing get 'linked' with a correct library.

"undefined symbol" TCC [duplicate]

I have learned that you can:
Convert a .DLL file into a .DEF file, which includes its exports
(Edit: This doesn't work with many conventions)
Convert a .DEF file into a .LIB file, which you can use to link to the DLL
Why can't (most) linkers link to a DLL given only a .DEF file, instead of a .LIB file?
Ultimately, the answer here is 'because noone wanted it badly enough and it doesn't really help anything'.
The DEF file is an input file that creates an import lib for the DLL. And then, later, when the DLL is being consumed by another link, the importlib is itself an input. The importlib looks like something special on the outside, but when you look at the inside it's really just a slightly special lib with objects in it.
It totally would be possible to modify the linker to take a def file (or a DLL, for that matter) directly.
But the design centre of the linker is that it takes objects as inputs and outputs a PE executable. So taking a DEF or DLL as an input goes outside the design pattern.
Beyond that it'd be rather pointless - allowing the linker to take a DEF file or DLL as input would neither enable any important new scenarios, nor does leaving this feature out block anything. Converting a DEF file you have (even without the actual DLL) into a usable importlib is the work of a few moments (simply create fake empty function for each DEF entry and link that). So there's no reason to add the ability to link a DEF file directly.
Martyn
In terms of MSVC, .lib files are always static libraries. They get linked in as a compilation unit along with all your compiled .c/.cpp files, so all of the library's code is included in your final executable.
Some .lib files, however, (in particular most of the Windows system ones) merely contain stubs which tell the OS to load the desired DLL at loadtime and then the stubs route function calls to the DLL. But, those stubs are statically linked into your executable. Your program will then use DLLs (and gain all the advantages and disadvantages thereof), but since the named DLL functions it requires are happily located in the .lib (and thus actually located in the executable itself), your code doesn't have to know it's using a DLL (specifically using declspec(dllimport)).
A .def file is merely used as a sort of "settings" or "configuration" file during the creation of a .dll to specify what functions the file should export. It cannot be linked to, as it doesn't really describe anything that the linker understands.
You do not convert a dll to a DEF file. The DEF just indicates which dll functions will be accessible from the outside, exported.
From the docs:
A DLL file has a layout very similar to an .exe file, with one
important difference — a DLL file contains an exports table. The
exports table contains the name of every function that the DLL exports
to other executables. These functions are the entry points into the
DLL; only the functions in the exports table can be accessed by other
executables. Any other functions in the DLL are private to the DLL.
The exports table of a DLL can be viewed by using the DUMPBIN tool
with the /EXPORTS option.
You can export functions from a DLL using two methods:
Create a module definition (.def) file and use the .def file when
building the DLL. Use this approach if you want to export functions
from your DLL by ordinal rather than by name.
Use the keyword __declspec(dllexport) in the function's definition.
When exporting functions with either method, make sure to use the
__stdcall calling convention.
Use the provided link to learn more about exporting from your dll's.
I think you got down voted because your point is not really clear, at least not to me. Also check this. It explains how to choose the export method.
Mehrdad, this isn't always a question of how to LINK to a DLL, as I, personally have NEVER linked a DLL using a .DEF file. What I HAVE done is take someone else's DLL, and very painstakingly constructed a header file, or rather, function prototypes that I could use with
LoadLibrary() in C, Declare Function ... Lib "Foo.dll" Alias "OrdinalName" in VB, and
[DllImport()] in C#.
Of course, this is RARELY done, as if you are using a DLL for something, normally you have permission to do so, and the authors provide the .lib's, and the headers to go with the binary DLL file.
I've never done the exact techniques you speak of, by converting a .DEF info a .LIB, etc... But, I suppose it would be easy to take a lib, or the DLL itself and export .DEF from it. Now, THAT I actually HAVE done, in a project where the DLL code was built with a vbScript that took code from the main project, and created an API out of all the existing, compiled, and tested code. This level of complication was only done because I had no idea what functions were going to BE in the DLL, as the main project could change at any time, so a static .DEF file would have never worked. So, I had to build the DLL once, capture the dimpbin /exports, undecorate the functions, and then build the .DEF file, and re-link the DLL.
If you find yourself in that type of situation, perhaps you need to re-think your original designs, and fix the problem from there...
As for .LIB files, USUALLY you'd only NEED those for static linkage, but they are also used when the .H file is available, often making debugging a just a little nicer...

Call static lib function embedded in DLL

Let's say the following architecture:
A static library is used/linked within a DLL
The DLL is loaded (either implicitly or explicitly) by an executable
Is it possible from the executable code to access code of the static library without relinking it explicitly nor inserting wrapper functions in the DLL?
In other terms, I am looking for a way to make a dll export of dependant static library code.
Given your constraints, the answer is no.
The reason is that the executable doesn't have any visibility into the dependencies or "call-ees" of the DLL. As far as the executable is concerned, he's just knows about the DLL itself: at link time, the executable knows only about those exports it is consuming from the DLL. He's going to LoadLibrary() against the DLL (which will fail if the dependencies of said DLL aren't resolvable), then call the exports of said DLL.
If you can't statically link with the library used by the DLL for some reason, another approach is to wrap the calls to said static library. This can be a pain of there are lots of calls, but there are automated tools which others have created to help. In particular I've used this before to create a wrapper for a DLL which exported hundreds of functions when I wanted to intercept a particular one: http://www.codeproject.com/KB/DLL/CreateYourProxyDLLs.aspx
The answer may easily be: Yes.
The only requirement is:
In your static LIB file you must define __declspec(dllexport) for all what you want to export.
When you then include this LIB file into your DLL project all the functions that you have declared as __declspec(dllexport) will be automatically DLL Exports and can be accessed from your Exe.

How to use the code of two DLLs from a third one in C?

I have two dll's a.dll and b.dll along with their library files a.lib and b.lib. I am trying to write a third dll that has functions that has to make use of functions in a.dll and b.dll.
Is this possible at all?
The output has to be a dll in itself - that is an absolute requirement.
I have the full C source code.
'Is this possible at all?'
In short, yes. DLLs can contain references to other DLLs in the same way that EXEs can. You don't say what compiler is being used, but it's likely that the 'lib' contains library references to the DLL. So, you would need to add these libraries into the linker configuration for your new DLL.
You'd typically reference any function prototypes from the other DLLs, via their header files (although you could prototype them again this seems unnecessary since you say you have the code), again this is the same as if you were using the DLL from an EXE.
You'd need to make sure all three DLLs are deployed together, since the new DLL references the existing ones, it does not take a copy of the functions into itself.

Resources