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.
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 .lib
s 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 dllexport
ed 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.