Visual-Studio: Efficiently Dealing With Cyclic Library Dependency - c++

I have a cross-language (C++ <-> FORTRAN) cyclic dependency that would be too much of a pain to eradicate, so I live with it. It only requires an occasional /FORCE with no linker dependencies on my C++ library. I have been doing this manually as required, but the new version of our product has eight configurations (and possibly more in future) and it is becoming more of a pain.
I could create 'Forced' configurations for each build in the Visual Studio configuration manager, or 'Forced' copies of my project(s). However, both these approaches are a bit of a maintenance headache - changes to the project have to be spread to all configurations / project copies.
Can anyone think of a method of quickly building my 'forced' configurations without have to flip-flop settings or maintaining a sync'd configuration just for that purpose?

As mentioned in the comments, if the DLL's are closely coupled it may make more sense just to combine them into a single DLL.
However, if two DLLs are still required, then one solution to this is to split one of the projects that currently builds a DLL into two - a static library project that also builds an import library and an exports file from a module definition file, and a second project that builds the DLL.
These two projects then bookend the construction of the other DLL.
For example, choosing to split the Fortran DLL, as I am more familiar with its project system:
Create a module definition file, with the same base name as will be used for the Fortran DLL, that lists in its exports section all the symbols that the Fortran DLL will export.
Create a Fortran static library project with a name different from that of the final Fortran DLL, that is configured to compile all the Fortran sources. In the project properties, as a custom build step add an additional invocation of the librarian along the lines of lib /DEF:xxx.def /OUT:xxx.dll /MACHINE:x86 (where xxx is the base name that will be used for the Fortran DLL - prepend configuration names as path suffixes as appropriate, vary the machine option as appropriate). Building this Fortran static library project will now generate two libraries - one with the object code (named after the project) and one that is the import library (named after the DLL) and an exports file (also named after the DLL).
[Note that with this approach the import library doesn't actually depend on the object code generated when the Fortran source files are compiled - use of the custom build step of the static library project is just a convenience. If you don't already have a module definition file for the Fortran DLL, an alternative approach is to instead supply the individual object files in the invocation of the librarian in the custom build step, and let the librarian determine the exports from any directives in the source files. However, I prefer module definition files to in source directives.]
Create a C++ project that holds all the C++ sources and builds the C++ DLL. That project should depend on the Fortran static library project and link against the import library generated by the Fortran static library project.
Create a Fortran DLL project, with the same base name as the Fortran DLL, that holds a dummy Fortran source file which only has comments inside it (this is just to avoid the build system getting confused). This DLL project should depend on the C++ DLL project, and link against the import library generated by the C++ project. In the project properties, under Linker > Input > Additional Dependencies, also add in the static library (not the import library!) and exports file generated by the Fortran static library project.
Other direct clients of the Fortran DLL should link against the import library generated by the custom build step of the Fortran static library project.
Variations on this approach are possible.

Related

visual studio 2015 c++ add a standalone dll file to a project

So I'm working on some libraries for c++ to make a beginner's experience easier. I've put the libraries into a standalone dll and now i want to add it to another project. But the thing is after searching the internet for ages, i have to have include directories and stuff but all i want is to include the single dll file to the project so the project can access the .h and .cpp files inside. Ik i can just add external jar with java then i can access the libraries in there but how do i do it with c++ in visual studio 2015?
This is not how C++ works (I also assume you're not talking about C++/CX or MC++ - which strictly speaking are not C++)
The C++ language does not define an "Application Binary Interface" - an ABI, which allows linking between binaries. That's an implementation concern.
There are ABIs that support C++, such as COM and CORBA, indeed the latest one is WinRT - itself based on COM.
C++ differs from languages like Java and C# which mandate a runtime which does have an ABI: Java has its .class and .jar files while .NET/C# has its CLR Metadata contained within its assembly (.dll files - which are not the same thing as "real" DLL files).
Note that DLL files generated by the C# compiler are nothing like DLL files generated by your C/C++ compiler toolchain's linker - while they share a common outer format as PE (Portable Executable) files, internally they are radically different: CLR DLLs contain CIL, an intermediate bytecode, whereas "real" DLLs contain native, processor-specific instructions.
The general way to work with other libraries in C++ is to either use them in source-form (as .c and .cpp files included in your project), or as .h header files with .lib (static libraries) which are almost similar to reusable binaries, except they're linked ("compiled into- and merged-with") into your finished binary and cannot be replaced at runtime.
The other way is with Dynamic Linking which requires your runtime (i.e. Win32) to do the runtime linking for you, usually with GetProcAddress - but this only exports C-style functions, not entire objects and classes (and certainly not any C++ templates).
In summary:
You have a DLL and you want to use code inside of it:
Is it a WinRT DLL?
If you want to use pure C++ then you need to use WTL. Beware, this approach is not for the faint-hearted.
Else, if you're okay with C++/CX then you can actually use the "Add Reference" UI in Visual Studio, but be advised, you're no-longer writing "real" C++ anymore.
Else is it a COM library?
(Note that you will need the ATL (Active Template Library) and the IDL definitions of the types contained within, this is the COM equivalent of a header file). You can also use #import and/or use the IDE to generate the actual .h and .c files needed to call COM without too much pain. However you will run into problems if you replace the COM DLL later without rebuilding your program if too many things were changed in a later COM DLL version (see "DLL Hell").
Else is it a traditional native Win32 PE DLL?
All a PE executable has is a list of exported functions and their address locations within the DLL.
Do you want Static Linking or Dynamic Linking?
For Dynamic Linking, do you want runtime resolution (painful, but flexible) or "automatic" linking?
For runtime linking you only need the .dll file and .h files. You will need to manually call GetProcAddress yourself for each function you want to call, then invoke it. An advantage is that you can detect at runtime if a function exists and gracefully handle linking errors.
For automatic linking you will be given a .lib file in addition to the .dll and .h files, the .lib file is a small statically-linked library that contains stubs and other code needed to perform the runtime linking for you without needing to manually call GetProcAddress yourself.
For Static Linking you won't have a .dll file, but a .lib file: known as a "static library". Inside it's a file that contains discretised executable function blobs which your linker will effectively copy+paste into your completed program.
How do you do it like Java? Well, you don't.
A header is required to provide the compiler with the prototypes of the functions and other symbols that are exported from the DLL that you might want to make use of. You may even have multiple header files to logically divide your DLL's code. And since you won't want to hard-code the path to these header files in your source code, you'll want to specify the path to its containing directory as part of your compiler/build options, freeing you to use relative paths.
A LIB file is generally also required, although this is slightly more flexible. Generally, a LIB makes things much easier. It will be generated by the linker when you compile the DLL, and it contains stubs that facilitate linking to functions exported by that DLL. You specify this LIB file in your linker options when building an application that uses the DLL, and things just work. This is called implicit dynamic linking. It's dynamic linking because you're using a DLL, but it's implicit because the linker is handling the dirty work for you.
If you don't want to use a LIB file, you will need to do explicit dynamic linking. This is still dynamic linking because you're still using the DLL, but it's explicit because you have to explicitly write code to load the DLL module and obtain pointers to functions that it exports. Microsoft's build tools provide various features to make this easier, but it's still more difficult than just using the LIB file, which is what I would recommend unless you have a good reason to do otherwise.

VS2010 static linking issue

my company has recently upgraded from VS2005 to VS2010. We have a huge project which uses a lot of modules which are being linked statically into the exe. But there seem to be some issues with linking in VS2010.
To explain our problem, we've built a minimal example project which is composed as shown on this graphic:
There is an application using one function from library A. Library A calls one function of each library B and library C. Those two libraries call a function provided by library D.
For Exe 1 under Framework and References we set everything to false except for Link Library Dependencies which is set to true. The only reference added is linking to library A. For each of the libraries all the settings are set to false. Library A gets references to only B and C, as well as those two getting references to D only. Library D has no references.
When building the application it works without problems. The application notices that library A is using library B and C which are using library D, so it knows it has to link those libraries, too. The libs are linked into the exe without problems.
Now we change something in, let's say, library D. Just a little difference, only one letter. Now we try to build the application again, it notices the change and re-compiles library D, but: It doesn't link to it anymore. The result are linking errors in library B and C, because they use library D. We have to run Rebuild first, in order to force the complete building and then everything is linked again.
This happens for both the minimal example as well as for our main project. Of course, we can add each of the libraries as additional dependency for the exe but it would be nice if it would work just like it does when building the project for the first time and continue to work after changes in the code. We noticed that when setting Use Library Dependency Inputs to true, that it works again, but then it doesn't link the *.lib files but the *.obj files which is not what we want of course.
Has anyone made similar experiences or has anyone a solution for this issue? Is this a buggy behavior of VS2010?
TIA.
p.s.: All libraries and executables are native C++.
Edit: (Workaround taken from this site)
In the file %ProgramsFile%\MSBuild\Microsoft.cpp\v4.0\Microsoft.CPPBuild.Targets there is a line
<Target Name="GetResolvedLinkLibs" Returns="#(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets)">
If you change that line to
<Target Name="GetResolvedLinkLibs" Returns="#(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets);ResolvedLinkLib">
the linking works properly and all needed libs are linked to implicitly. The linker output not only shows lib_a.lib but also all other chained libs, lib_b, lib_c, lib_d without having them added manually as dependencies to the exe.
This seems to be more a workaround then a solution, maybe there is a proper way to achieve implicit linking.
Have a look at following links:
Visual Studio 2010 not autolinking static libraries from projects that are dependencies as it should be supposed to
Behavior of Link Library Dependencies in 2010
Unresolved Externals When Build a VC++ Project with Chained Static Lib Dependencies
Flexible Project-to-Project References
I only know that I had such similar situations because of wrong using of Libraries with same name but with different architecture. lets say, I have an Dll (lets call it mydll.dll) for x86 and will import it into my project it will work. If I will do the same with x64 dll (same name mydll.dll) it will work.
But if I want to include both libraries it is not allowed to only rename it into mydllx86.dll / mydllx64.dll. I CAN include now both libraries into Visual Studio. But when compiling it or restarting visual studio, one of both libraries will be unaccessable anymore.
In this case I perhaps it helps to have a look into library architecture and used namespaces / Api names.
Regards
You are pretty lost in that dialog if you are tinkering with Framework and References, those are settings that only apply to managed code. The term "reference" only applies to .NET assemblies. The linker doesn't support storing compiled managed code in a .lib. I'll work from the assumption that you actually are changing linker settings. If you make a change in library D then you also have to change its header file. Which in itself will be enough to get B and C rebuilt since one or more of their source code files should #include that header.
The only thing that Link Library Dependencies does is automatically make a .lib a dependency, same thing as Linker + Input, Additional Dependency setting. That however requires you to explicitly set the project dependencies. Right-click the B project, click Project Dependencies and tick D. Repeat for C. Repeat for A and tick B and C. Repeat for EXE and tick A.
This is rarely what you want, it makes the D library embedded into the B and C libraries. And B and C get embedded in A. The EXE now only has a dependency on A. It works, but it makes the .lib files unnecessarily beefy. And you have the problem you describe if you don't set the project dependencies properly, a rebuild of D doesn't cause it B and C to be relinked.
What you should do is not set dependencies between the .libs, they don't have any. Each can be built without the other .libs being present. A .lib is nothing but a bag of .obj files. All that's required is that you make all 4 .lib projects dependencies of the EXE project. That makes sure that they are built before the linker tries to link the EXE.
We starting seeing this issue again after moving to Visual Studio 2015 (and also in VS2017). The problem only seems to exist in the following configuration:
Project (EXE)
--> Static Library A (Reference)
--> Static Library B (Specified in Linker->Additional Dependencies)
--> Static Library C (Not in solution, specified in Linker->Additional Dependencies)
There are several other projects in the solution that use A and B. When something in project B or C changes, many of these projects give LNK4099 warnings.
In our case, the solution is to use the following:
Code Generation > Output Files > Program Database File Name: $(TargetDir)$(TargetName).pdb
Librarian > General > Output File: $(TargetDir)$(TargetName)$(TargetExt)
$(TargetDir) uses an absolute path versus the default $(OutDir) which in our case was relative. It seems that the correct path gets lost with multiple levels of indirection.
One interesting thing is if you switch the number of compile threads to 1, it doesn't appear to happen (maybe some kind of race condition within Visual Studio?).

Static library with dependencies

e.exe is linked against my custom static library, c.lib, which uses Win32 API defined in w.dll. w.dll is located in C:\Windows\System32 and its import library is w.lib, located in Windows SDK directory. Shell w.lib be listed as Additional Dependency in c.lib or e.exe project? (e.exe builds successfully in both cases.) What is the best practice and why? I guess e.exe should not know about w.lib.
c.lib is intended to be shared among a group of developers only (not to be shipped to customers).
TEST: I used VS2008 and dumpbin utility to test both cases and here are results:
Case 1: w.lib added as Additional Dependency in c.lib project.
dumpbin /archivemembers c.lib output lists both offsets in w.dll and .obj files from c.lib project as Archive members.
Case 2: w.lib not added as Additional Dependency in c.lib but in e.exe project:
This time, dumpbin output contains only .obj files of c.lib and the size of c.lib is smaller than in Case 1
(c.lib was added as Additional Dependency in w.exe project in both cases.)
NOTE: I used w.lib and w.dll here as fictional, generic names for Windows libraries but they could be e.g. Userenv.lib and Userenv.dll or Version.lib and Version.dll...
I think you're misunderstanding what creating an archive and an import archive does.
Creating an archive, as you've rightly surmised in comments, creates a unified file containing compiled .objs. Now, this can contain any code you like, including but not limited to dynamic calls to libraries. An import library is a library that contains an obj that exclusively makes such calls, the idea being that by importing it, your exe can find the appropriate symbols (they must be in the executable you create).
The process of creating c.lib from w.lib simply extracts w.lib's objects and appends them to the collection of objects in c.lib. In effect, c.lib becomes an import library + code.
Do I think you should do this? Not really - it might lead to confusion as to what e.exe depends on; I think you should explicitly make this visible rather than trying to hide it. That said, that's a recommendation only, not a rule.
Libraries are not linked, so any project that uses a .lib also needs its dependencies.
Basically the .lib are "copied" to your exe during linking.
If you want to avoid your users to explicity link againts w.lib, transforms c.lib in a dll, dlls are linked and you do not need their dependencies during build.

No additional dependencies required for a LIB but are required for a DLL

I have a framework (in C++) which is dependent on a few third party libraries. When I compile a static version of the library framework, no additional dependencies are needed, that is, the lib files of the third part libraries are not needed. When I compile the same framework as a DLL, additional dependencies are now needed otherwise I get linking errors. I can guess as to why this is happening but would like a concrete answer/explanation to understand what is happening.
EDIT: Just to clarify, I am developing a framework which can be compiled as a lib and as a dll and then used in a(n) (executable) project. When compiling the framework as a lib and using functions from a third party library, I don't need additional dependencies. However, a project that now uses the lib file (which is the framework) must include the 3rd party lib files. When I compile the framework as a dll it gives me linking errors unless I specify the 3rd part libraries the framework is technically dependent on. For example: I have a few classes that call functionality from within Ogre3D. These classes are compiled as a lib file. I don't need to link against OgreMain.lib when compiling a lib of the classes. On the other hand, when I am compiling a dll version of the same classes, I now need to link against OgreMain.lib
When you have a static library (a .lib file), which is just a collection of one or more object files (.obj), the linker just adds that code to yours in one executable. You can tell the linker to do this via a command line switch, an IDE configuration setting, or perhaps even a #pragma (specifics depend on your environment and compiler).
When you link in a DLL, you need to give the linker some code to call when you invoke one of the DLLs functions. Usually, this is done with a file of the same name as the .dll, save that it is a .lib. The code in that .lib is linked into your program the same way as described above, but when you call it, it loads the DLL (if not already loaded) and then invokes the proper function.
There are other ways to handle DLL linking (for instance, .def files or #using statements in .NET), but this seems to be what you're talking about.
Responding to your question clarification:
The issue is that a .lib is not a final product. It is just an aggregation of object code to be used later when a linker connects all your functions calls to function addresses.
A DLL, on the other hand, is a final product, and so the linker requires all functions and variables be connected to actual addresses.
I'm speaking a bit imprecisely, but you get the idea.
A static library can include other static libraries, providing a single lib to link
A DLL can include static libraries, providing a single DLL to link.
A DLL or static library with dependencies on other DLLs has no way to combine them so your executable must explicitly link to those other DLLs.
When you link to a LIB it adds all the symbols/functions you actually use to your executable. The ones you don't use won't get added. When you link to a dll - all the code from the external library gets loaded. If this additional code (code you don't use) depends on more external libraries you need to provide these as well.
One example: You want to use a ip class from a network library. The ip class does not depend on other libraries. Other functions in the network library depend on other external libraries. If you link the network library as a LIB you just link the ip class -> you don't need the other libraries since the other code wont get linked. When you use the DLL all code in the dll need to be instanciated -> so you will need to provide the other external libraries.
Building a DLL is more like building an application than a library. The difference between building an application and a DLL is knowledge of what might be called. In an application all symbols that are not used can be discarded in the build, but in a DLL you cannot strip symbols that are not used - that would be all of them...
You would find the same link problems in your static libraries if you where able to call all the symbols that the DLL links.

How does the Import Library work? Details?

I know this may seem quite basic to geeks. But I want to make it crystal clear.
When I want to use a Win32 DLL, usually I just call the APIs like LoadLibrary() and GetProcAdderss(). But recently, I am developing with DirectX9, and I need to add d3d9.lib, d3dx9.lib, etc files.
I have heard enough that LIB is for static linking and DLL is for dynamic linking.
So my current understanding is that LIB contains the implementation of the methods and is statically linked at link time as part of the final EXE file. While DLL is dynamic loaded at runtime and is not part of the final EXE file.
But sometimes, there're some LIB files coming with the DLL files, so:
What are these LIB files for?
How do they achieve what they are meant for?
Is there any tools that can let me inspect the internals of these LIB files?
Update 1
After checking wikipedia, I remember that these LIB files are called import library.
But I am wondering how it works with my main application and the DLLs to be dynamically loaded.
Update 2
Just as RBerteig said, there're some stub code in the LIB files born with the DLLs. So the calling sequence should be like this:
My main application --> stub in the LIB --> real target DLL
So what information should be contained in these LIBs? I could think of the following:
The LIB file should contain the fullpath of the corresponding DLL; So the DLL could be loaded by the runtime.
The relative address (or file offset?) of each DLL export method's entry point should be encoded in the stub; So correct jumps/method calls could be made.
Am I right on this? Is there something more?
BTW: Is there any tool that can inspect an import library? If I can see it, there'll be no more doubts.
Linking to a DLL file can occur implicitly at compile link time, or explicitly at run time. Either way, the DLL ends up loaded into the processes memory space, and all of its exported entry points are available to the application.
If used explicitly at run time, you use LoadLibrary() and GetProcAddress() to manually load the DLL and get pointers to the functions you need to call.
If linked implicitly when the program is built, then stubs for each DLL export used by the program get linked in to the program from an import library, and those stubs get updated as the EXE and the DLL are loaded when the process launches. (Yes, I've simplified more than a little here...)
Those stubs need to come from somewhere, and in the Microsoft tool chain they come from a special form of .LIB file called an import library. The required .LIB is usually built at the same time as the DLL, and contains a stub for each function exported from the DLL.
Confusingly, a static version of the same library would also be shipped as a .LIB file. There is no trivial way to tell them apart, except that LIBs that are import libraries for DLLs will usually be smaller (often much smaller) than the matching static LIB would be.
If you use the GCC toolchain, incidentally, you don't actually need import libraries to match your DLLs. The version of the Gnu linker ported to Windows understands DLLs directly, and can synthesize most any required stubs on the fly.
Update
If you just can't resist knowing where all the nuts and bolts really are and what is really going on, there is always something at MSDN to help. Matt Pietrek's article An In-Depth Look into the Win32 Portable Executable File Format is a very complete overview of the format of the EXE file and how it gets loaded and run. Its even been updated to cover .NET and more since it originally appeared in MSDN Magazine ca. 2002.
Also, it can be helpful to know how to learn exactly what DLLs are used by a program. The tool for that is Dependency Walker, aka depends.exe. A version of it is included with Visual Studio, but the latest version is available from its author at http://www.dependencywalker.com/. It can identify all of the DLLs that were specified at link time (both early load and delay load) and it can also run the program and watch for any additional DLLs it loads at run time.
Update 2
I've reworded some of the earlier text to clarify it on re-reading, and to use the terms of art implicit and explicit linking for consistency with MSDN.
So, we have three ways that library functions might be made available to be used by a program. The obvious follow up question is then: "How to I choose which way?"
Static linking is how the bulk of the program itself is linked. All of your object files are listed, and get collected together in to the EXE file by the linker. Along the way, the linker takes care of minor chores like fixing up references to global symbols so that your modules can call each other's functions. Libraries can also be statically linked. The object files that make up the library are collected together by a librarian in a .LIB file which the linker searches for modules containing symbols that are needed. One effect of static linking is that only those modules from the library that are used by the program are linked to it; other modules are ignored. For instance, the traditional C math library includes many trigonometry functions. But if you link against it and use cos(), you don't end up with a copy of the code for sin() or tan() unless you also called those functions. For large libraries with a rich set of features, this selective inclusion of modules is important. On many platforms such as embedded systems, the total size of code available for use in the library can be large compared to the space available to store an executable in the device. Without selective inclusion, it would be harder to manage the details of building programs for those platforms.
However, having a copy of the same library in every program running creates a burden on a system that normally runs lots of processes. With the right kind of virtual memory system, pages of memory that have identical content need only exist once in the system, but can be used by many processes. This creates a benefit for increasing the chances that the pages containing code are likely to be identical to some page in as many other running processes as possible. But, if programs statically link to the runtime library, then each has a different mix of functions each laid out in that processes memory map at different locations, and there aren't many sharable code pages unless it is a program that all by itself is run in more than process. So the idea of a DLL gained another, major, advantage.
A DLL for a library contains all of its functions, ready for use by any client program. If many programs load that DLL, they can all share its code pages. Everybody wins. (Well, until you update a DLL with new version, but that isn't part of this story. Google DLL Hell for that side of the tale.)
So the first big choice to make when planning a new project is between dynamic and static linkage. With static linkage, you have fewer files to install, and you are immune from third parties updating a DLL you use. However, your program is larger, and it isn't quite as good citizen of the Windows ecosystem. With dynamic linkage, you have more files to install, you might have issues with a third party updating a DLL you use, but you are generally being friendlier to other processes on the system.
A big advantage of a DLL is that it can be loaded and used without recompiling or even relinking the main program. This can allow a third party library provider (think Microsoft and the C runtime, for example) to fix a bug in their library and distribute it. Once an end user installs the updated DLL, they immediately get the benefit of that bug fix in all programs that use that DLL. (Unless it breaks things. See DLL Hell.)
The other advantage comes from the distinction between implicit and explicit loading. If you go to the extra effort of explicit loading, then the DLL might not even have existed when the program was written and published. This allows for extension mechanisms that can discover and load plugins, for instance.
These .LIB import library files are used in the following project property, Linker->Input->Additional Dependencies, when building a bunch of dll's that need additional information at link time which is supplied by the import library .LIB files. In the example below to not get linker errors I need to reference to dll's A,B,C, and D through their lib files. (note for the linker to find these files you may need to include their deployment path in Linker->General->Additional Library Directories else you will get a build error about being unable to find any of the provided lib files.)
If your solution is building all dynamic libraries you may have been able to avoid this explicit dependency specification by relying instead on the reference flags exposed under the Common Properties->Framework and References dialog. These flags appear to automatically do the linking on your behalf using the *.lib files.
This however is as it says a Common Properties, which is not configuration or platform specific. If you need to support a mixed build scenario as in our application we had a build configuration to render a static build and a special configuration that built a constrained build of a subset of assemblies that were deployed as dynamic libraries. I had used the Use Library Dependency Inputs and Link Library Dependencies flags set to true under various cases to get things to build and later realizing to simplify things but when introducing my code to the static builds I introduced a ton of linker warnings and the build was incredibly slow for the static builds. I wound up introducing a bunch of these sort of warnings...
warning LNK4006: "bool __cdecl XXX::YYY() already defined in CoreLibrary.lib(JSource.obj); second definition ignored D.lib(JSource.obj)
And I wound up using the manual specification of Additional Dependencies to satisfy the linker for the dynamic builds while keeping the static builders happy by not using a common property that slowed them down. When I deploy the dynamic subset build I only deploy the dll files as these lib files are only used at link time, not at runtime.
Here are some related MSDN topics to answer my question:
Linking an Executable to a DLL
Linking Implicitly
Determining Which Linking Method to Use
Building an Import Library and Export File
There are three kinds of libraries: static, shared and dynamically loaded libraries.
The static libraries are linked with the code at the linking phase, so they are actually in the executable, unlike the shared library, which has only stubs (symbols) to look for in the shared library file, which is loaded at run time before the main function gets called.
The dynamically loaded ones are much like the shared libraries, except they are loaded when and if the need arises by the code you've written.
In my mind, there are two method to link dll to exe.
Use dll and the import library (.lib file) implicitly
Use functions like loadlibrary() explicitly