Proper way to link static libraries with dll - c++

My project builds through few static libraries which should linked to main dll library gain one single dll as a result.
Using __declspec(dllexport) attribute does not lead to appearance of specified functions of static libraries to dll, libraries not linked with dll at all.
Then I tried to build each library as shared for getting proper names of exported functions and created .def file based on them. Using .def file leaded to result.
Should __declspec(dllexport) and .def-file act equally in my case?
Is it possible to generate a .def file from sources? Since I have C++ code I'm not able to write .def file by myself because of mangling and presence classes in API, the approach described above with temporary generated dlls is inconsistent for production.
Update
I'd like to explain in detail about the structure of my project. The solution consists of a few projects (modules).
+
|
+-+ static_lib1
| +
| +--+ src
|
+-+ static_lib2
| +
| +--+ src
|
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
+
+--+ src
Each sub-project weakly depends on others, let's assume they are not connected for clearness. Each module has own public interface. I want to have all modules as single dynamic library so my artifact is dynamic_lib.dll, but in fact static libraries are not linked with it.

Static libraries should not contain any __declspec or __attribute((dll...)) things. They are nothing more than multiple object files (usually *.obj or *.o), composed into one, single file.
All you need to do in order to use such library (either in .exe or .dll) is to include proper headers and link them - with Visual Studio it's pretty easy.
First of all, you need to know 1) where your static libraries are placed and 2) their exact names. Go to project properties and then General. Target name contains name for the output file, while Output directory indicates in which folder your .lib will be placed.
Note: This path may be different for every project! For multi-project solution, I always set this to a common path to avoid configuration problems.
Now, go to properties of project, that will consume this library (link with it). Go to Linker -> Input and then add name of your .lib to Additional dependencies (entries are separated with semicolon):
You need to add all libraries you want have linked in. Also, folder, in which these libraries are placed, must added to Linker -> General -> Additional library directories. If all .libs are placed in the same place - good, otherwise copy them into shared location or add multiple entries to Additional library directories list.
And the last thing - remember, that you also need to include headers with declarations of functions and objects, that you want to use. Basic thing, I know, but has to be mentioned.
UPDATE
unresolved external when trying to use dll library in an external prodjects
Your problem is not related to linking at all. The thing is, that you misunderstood what, linking a static library exactly does.
I am guessing, that functions reported as unresolved are not used by your DLL, right? But you expect them to be inside it, right?
When your DLL refers to an external content (like function or variable), it is resolved at linking time - together with all dependencies. But that's all. If your static library has a function named print_sample_string(), but your DLL does not use it, it won't be attached to DLL image. Think about this carefully - why should it be?
Even more - functions, that are not dllexported explicitly won't be visible anyway. Functions have by default external storage - so basically, they are private DLL's content.
So to answer your question directly - if you need to use functions/variables from static_lib1.lib, attach it to client application - just like you are attaching it now to dynamic_lib. There is no other way. (*)
(*) Truly speaking - there is. You can create intermediate function in DLL, that is exported and call desired function inside:
Somewhere in dynamic_lib:
DLL_EXP_IMP long CallFunctionFromA_Lib()
{
return some_function(); //this function is from static_lib1.lib
}
Somewhere in .exe:
long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib
I can't imagine, however, why would you want to do this and not simply link A.lib and use it directly.

Here Raymond Chan explains this behavior and the best solution is really just to use def file. As for how to generate it automatically for static a library - this discussion looks like a good starting point.

Related

How to add 2 different C libraries with same name but having entirely different functionalities without changing the name?

How to add 2 different C libraries with same name but having entirely different functionalities without changing the name?
For example one s/w product comes with lib named libabc.so
And my lib is also having the same name libabc.lib.
So, how I can use the both the lib at the same time, without conflicting at runtime
Instead of linking with -labc link with the full file library file paths like /usr/local/lib/libabc.a ./mylib/libabc.a for example.
If you do that the fact that they have the same name shouldn't matter.
What may conflict is if both libraries export symbols with identical names.
If header files also have the same name (e.g. abc.h) your #include statements may also need full paths to make sure you're including the right file.

How to link your external library dependencies into one static library file in VS2015

This is the situation.
I have a library project A that uses and manipulates other third party libraries, we call them T1 and T2.
However when I use this library A in any of my other projects it complains that it cannot open the third party libraries T1 and T2 even though it does not directly uses them. Ofcourse it indirectly uses them through library A because A did the appropriate work to link and include against that library etc.
Do I really need to add these other libraries to the projects that use library A or is there a way to lets say concatenate libraries such that the user of library A only ever needs to worry about that one instead of what its made of.
Edit:
Found some related questions but the answers do not quite solve the
issue;
linking-static-libraries-to-other-static-libraries
how-to-combine-several-c-c-libraries-into-one
Edit2:
Thanks for the answers so far. Let me clearify my situation.
I have a .lib project in VS2015 which we call MathLib. This MathLib uses lets say a boost library internally to do its calculations, lets call this library BoostMath. The property files are all set to include and use this BoostMath and this works perfectly in the library project itself.
I am now making another project User that uses the MathLib to do its calculations. It does the appropriate includes and all to use this library. However it complains about the fact that it does not know the BoostMath library and thus cannot work with the MathLib library.
One could argue why not just include BoostMath into project User in the same manner that the MathLib library did this, but that is missing the point. I want to create a library of my own that may or may not use other libraries internally but this should not be of any concern to the end user of my library.
I probably have to set something in VS Librarian to make this happen, concatenate the libs together or some. But I cannot seem to figure it out. Any thoughts?
Edit3:
I even found the exact same commandline in the property files as mentioned in this answer.
/OUT:"MathLib.lib" "BoostMath.lib" /NOLOGO /LIBPATH:"path\lib"
However it does not work for some reason. If I run it with and without the Librian property setting, the .lib binary stays the same.
Appearantly this functionality is broken since VS2010? According to this answer.
Usefull other question.
Edit4:
I basically want to do this, but it does not seem to work in VS2015
+---------------+
| End user exe |
+---------------+
|
| some api call
|
+---------------+
| My MathLib |
+---------------+
|
|
+---------------+------------+----
| | |
+-----+------+ +-----+-----+
| BoostMath | | OtherMath |
+------------+ +-----------+
I am not sure how you link the library to the project...but it should not complain the compiler could not open the library T1 and T2 unless you have included those in the compiler setting.
Normally if you don't have the library, it will report could not find the function example T1_xxxx (this function is defined in T1). I would suggest you check the compiler setting of the project
Basically static libraries do not undergo linkage, and in particular static libraries have no way to specify their own dependencies. You can partially hack around this by spreading #pragma comment(lib)'s around individual obj files (i.e., individual source files), but not at the library level - and it seems you don't intend to modify the lib sources anyway.
Your best option seems to be combining the lib along with its dependencies into a single lib, as specified e.g. here:
lib.exe /OUT:compositelib.lib lib1.lib lib2.lib
Note that you'd have to re-package whenever any of the dependencies change. I myself, as a user, would prefer to include all the referenced libs in my consumer solution.

How to bind static library in a dynamic one in Code::Blocks

I have this static(.a/.lib) library which I wanted to bind in my dynamic(.dll).
Lets say the static library is libColors.a and the dynamic is SWC.dll.
Now I already change the libColors.a project properties to make a static library--build it--and I haven't found any .dll created, only the .o and .a files which is expected. I switched to my SWC.dll project and change its properties to make a dynamic library and check the box to create also a .a file--link the libColors.a--build it--and the .dll file is created. (also note that I put __declspec(import/export) specification on its classes)
Now I want this SWC.dll to use in an executable file. However, when I include only the SWC.h file in the executable, it gets tons of undefined references. Seems there's a problem here since I didn't call any functions on SWC.h. So, I add on my .exe build options the SWC.a, now it builds with no error. But when I run it, it says I needed the Colors.dll? What do I miss?
You can use tools like objdump, CFF Explorer or Dependency Walker to view the import table of the PE-COFF executable in question.
The likely explanation is that the way your Colors project is compiled isn't really a static library. You can check this by inspecting both SWC.dll and your test executable's import table. Chances are that you'll find an import entry from Colors.dll in one of them and what function's it's trying to import.
Check the data and functions declared in Color.h and make sure they're not decorated with __declspec() anywhere. If the functions in Color.h preprocesses into something like __declspec(dllimport) in 'SWC' this can cause the problem you're seeing.

why do I need to link a lib file to my project?

I am creating a project that uses a DLL. To build my project, I need to include a header file, and a lib file. Why do I need to include the respective lib file? shouldn't the header file declare all the needed information and then at runtime load any needed library/dll?
Thanks
In many other languages, the equivalent of the header file is all you need. But the common C linkers on Windows have always used import libraries, C++ linkers followed suit, and it's probably too late to change.
As a thought experiment, one could imagine syntax like this:
__declspec(dllimport, "kernel32") void __stdcall Sleep(DWORD dwMilliseconds);
Armed with that information the compiler/linker tool chain could do the rest.
As a further example, in Delphi one would import this function, using implicit linking, like so:
procedure Sleep(dwMilliseconds: DWORD); stdcall; external 'kernel32';
which just goes to show that import libraries are not, a priori, essential for linking to DLLs.
That is a so-called "import library" that contains minimal wiring that will later (at load time) ask the operating system to load the DLL.
DLLs are a Windows (MS/Intel) thing. The (generated) lib contains the code needed to call into the DLL and it exposes 'normal' functions to the rest of your App.
No, the header file isn't necassarily enough. The header file can contain just the declarations of the functions and classes and other things you need, not their implementations.
There is a world of difference between this code:
void Multiply(int x, int y);
and this code:
void Multiply(int x, int y)
{
return x * y;
}
The first is a declaration, and the second is a definition or implementation. Usually the first example is put in header files, and the second one is put in .CPP files (If you are creating libraries). If you included a header with the first and didn't link in anything, how is your application supposed to know how to implement Multiply?
Now if you are using header files that contain code that is ALL inlined, then you do not need to link anything. But if even one method is NOT inlined, but has its implementation in a .CPP file that is compiled to a .lib file, than you need to link in the .lib file.
[EDIT]
With your use of Import Libraries, you are telling the linker to NOT include the implementation details of the imported code into your binary. Instead the OS will then load the import DLL at run-time into your process. This will make your application smaller, but you have to ship another DLL with it. If the implementation of the library changes, you can just reship another DLL to your customers, and not have to reship the entire application.
There is another option where you can just link in a library and you don't need to ship another DLL. That option is where the Linker will include the implementation into your application, making it bigger in size. If you have to change the implementation details in the imported library, then you have to recompile and relink your entire application, and reship the entire thing to your customers.
There are two relevant phases in the building process here:
compilation: from the source code to an object file. During the compilation, the compiler needs to know what external things are available, for that one needs a declaration. Declarations designed to be used in several compilation units are grouped in header. So you need the headers for the library.
linking: For static libraries, you need the compiled version of the library. For dynamic libraries, in Unix you need the library, in windows, you need the "import library".
You could think that a library could also embed the declarations or the header could include the library which needs to be linked. The first is often done in other languages. The second is sometimes available through pragmas in C and C++, but there is no standard way to do this and would be in conflict with common usage (such as choosing a library among several which provide code variant for the same declarations, for instance debug/release single thread/multithreads). And neither choice correspond well with the simple compilation model of C and C++ which has its roots in the 60's.
The header file is consumed by the compiler. It contains all the forward declarations of functions, classes and global variables that will be used. It may also contain some inline function definitions as well.
These are used by the compiler to give it the bare minimum information that it needs to compile your code. It will not contain the implementation details.
However you still need to link in all the function, and variable definitions that you have told the compiler about. Failure to do so will result in a linker error. Often this is contains in other object files which may be joined into a single static library.
In the case of DLLs (or .so files), we still need to tell the linker where in the DLL or shared object the missing symbols are. On windows, this information is contained in a .lib file. This will generate the code to load and link the code at runtime.
On unix the the dll and lib files are combined into a single .so file which you must link against to about linker errors.
You can still use a dll without a .lib file but you will then have to load and link in all the symbols manually using operating system APIs.
from 1000 ft, the lib contains the list of the functions that dll exports and addresses that are needed for the call.

LNK4221 and LNK4006 Warnings

I am making a static library of my own. I have taken my code which works and now put it into a static library for another program to use. In my library I am using another static library which I don't want the people who will be using my API to know. Since, I want to hide that information from them I can't tell them to install the other static library.
Anyway, I used the command line Lib.exe to extract and create a smaller lib file of just the obj's I used. However, I get a bunch of LNK4006 :second definition ignored linker warnings for each obj I use followed by LNK4221 no public symbols found;archive member will be inaccessible.
I am doing this work in vs2008 and I am not sure what I am doing wrong.
I am using the #pragma comment line in my .cpp file
I have also modified the librarian to add my smaller .lib along with its location.
my code simply makes calls to a couple functions which it should be able to get from those Obj file in the smaller lib.
All my functions are implemented in .cpp file and my header just have the includes of the third party header files and come standard c++ header files. nothing fancy. I have actually no function definitions in there atm. I was going to put the API definition in there and implement that in the .cpp for this static lib that i was going to make. However, I just wanted to build my code before I added more to it.
I did read http://support.microsoft.com/default.aspx?scid=kb;EN-US;815773 but it did not provide a solution.
Even if you extract all objects from the other library and put them in your own library, your users will still be able to see what's in your library and thus see all the object names. In many cases the names of the objects will reveal what's actually the other library you are using.
Instead of distributing your library as a static library, consider distributing it as a DLL. In the DLL you can easily hide all the underlying things and only make public what you want to make public.