I generated a *.dll with VC++. When I want to use it, a *.lib is required. But I cannot find it. How to get the *.lib? Thanks.
Unless you specify otherwise, the .lib will be generated in the same directory as the .DLL.
If you're getting a dll but not a lib, chances are pretty good that somehow or other you're not actually exporting anything from the dll. In such a case, the linker will create the dll, but won't automatically create a matching import library.
This really depends on your project settings.
Take a look at *.vcprojx
and search for similar pattern:
<link>
<ImportLibrary>.\Release/yourlibrary.lib</ImportLibrary>
</link>
Usually, Visual Studio puts the .lib right next to the .dll file.
YOur case sounds like it wouldn't generate a .lib at all. When building libraries as dll, if you want to link to that library in another project (as opposed to using dllopen and the likes), you have to specify which functions should be exported to a lib. For this, you have to prepend all classes or functions you want to export with a __declspec(dllexport) when building the library, and __declspec(dllimport) when linking it.
What you often find is some macro like this:
#ifdef WIN32
#ifdef MYLIB_EXPORTS
#define MYLIBAPI __declspec(dllexport)
#else
#define MYLIBAPI __declspec(dllimport)
#endif
#else
#define MYLIBAPI
#endif
Then, when building the lib, you define the MYLIB_EXPORTS preprocessor, so that it exports, while linking against it imports. Your own Code could then look like this
class MYLIBAPI MyClass
{
public:
void SomeFunction()
}
MYLIBAPI void SomeGlobalFunction();
Now, MyClass and SomeGLobalFunction are exported when building, and occur in the lib file.
Related
I had a question about DLL building / linking in Visual Studio 2005 and later. Basically my understanding and experience is this:
To build a DLL, I specify the project properties to build a DLL, and then I but __declspec(dllexport) in front of any functions or members that I want to publically expose from the DLL. Building the project will result in a DLL, a Lib, and a header file that can be deployed as say an API or something.
On the other end, to have your other compiled executable application dynamically link to the DLL and use its functions, you simply need to have your executable project include the header files and link with the small lib file that was created when the DLL was built. As long and the compiled application can find the DLL, everything will work.
That has been my experience and that is also how the Microsoft DLL building tutorial described everything on MSDN. I am wondering: is this standard practice? When would you ever need to use __declspec(dllimport) anywhere? Am I missing something?
Thanks!
Yes you would use __declspec(dllimport) and you generally have a macro that controls whether a source file either exports (if it's part of your DLL) or imports (if it's part of the using-executable) symbols.
In your DLL you can set a manifest constant to the build settings of some sort, say 'BUILDING_MY_DLL' and then create the macro like this within your header file:
#ifdef BUILDING_MY_DLL
#define MY_DLL_EXPORT __declspec(dllexport)
#else
#define MY_DLL_EXPORT __declspec(dllimport)
#endif
and then decorate your exported functions like this:
MY_DLL_EXPORT int func(int y);
You can also export entire classes this way too:
class MY_DLL_EXPORT InterestingClass
{
...
};
I had a question about DLL building / linking in Visual Studio 2005 and later. Basically my understanding and experience is this:
To build a DLL, I specify the project properties to build a DLL, and then I but __declspec(dllexport) in front of any functions or members that I want to publically expose from the DLL. Building the project will result in a DLL, a Lib, and a header file that can be deployed as say an API or something.
On the other end, to have your other compiled executable application dynamically link to the DLL and use its functions, you simply need to have your executable project include the header files and link with the small lib file that was created when the DLL was built. As long and the compiled application can find the DLL, everything will work.
That has been my experience and that is also how the Microsoft DLL building tutorial described everything on MSDN. I am wondering: is this standard practice? When would you ever need to use __declspec(dllimport) anywhere? Am I missing something?
Thanks!
Yes you would use __declspec(dllimport) and you generally have a macro that controls whether a source file either exports (if it's part of your DLL) or imports (if it's part of the using-executable) symbols.
In your DLL you can set a manifest constant to the build settings of some sort, say 'BUILDING_MY_DLL' and then create the macro like this within your header file:
#ifdef BUILDING_MY_DLL
#define MY_DLL_EXPORT __declspec(dllexport)
#else
#define MY_DLL_EXPORT __declspec(dllimport)
#endif
and then decorate your exported functions like this:
MY_DLL_EXPORT int func(int y);
You can also export entire classes this way too:
class MY_DLL_EXPORT InterestingClass
{
...
};
I want to create a dll that exports a function and a struct. I went through the walkthrough and here is what I have:
Project myDll: the_dll.h
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
typedef struct MyStruct
{
bool b;
} MYSTRUCTTYPE, *PMYSTRUCTTYPE;
typedef const MYSTRUCTTYPE *MYCSTRUCTTYPE;
MYDLL_API bool dllF();
Project myDll: the_dll.cpp
#include the_dll.h
bool dllF() { return true };
In the Preprocessor definitions of the myDll project, I define MYDLL_EXPORTS
In Linker -> Advanced -> Import Library I see $(OutDir)$(TargetName).lib
Yet there is no lib generated, only dll and pdb
Intellisense shows MYDLL_EXPORTS to be __declspec(dllexport) and the dllimport portion is grayed out... So I must be exporting...
I have included the dependent header file, and set the additional library directories and additional include directories, as well as dependent libs, in the caller project. But... in the absence of the lib...
The project that requires the functions from this dll gives unresolved external symbol error.
How can I make my dll create a lib ? What am I missing ? (Or... how can I use its functions without linking to a lib and include a header ?)
Note: I assume the structs and typedefs do not need to be exported... true ?
Update: as I wrote in comment, the project did create a lib when I imported it into a different solution and erased all the debug folders... I have been "Build -> Clean Solution" between tries but I suppose something did not get cleaned ...
So the true reason for not getting a lib created was (my guess) that, while experimenting with the code and before adding the definition for MYDLL_EXPORTS, files where created that did not get cleaned... I will always delete the build folders before trying again, in the future.
I checked with a small test project in VS2013. It produced .lib files for both my DLLs in the Debug directory. This means that if the setup is not screwed up, using default settings you should have implib after building the DLL.
In fact, you need .lib file only if you want to distribute your dll to customers. If you want to use this dll in the same solution by other projects, do the following:
Select project where you want to import functions.
On the top menu click PROJECT->References....
Click button "Add New Reference" at the mid bottom.
Select dlls that you want to import from.
Close all dialogs with OK.
Rebuild your solution.
Structures cannot be exported. They are communicated to other binaries using header files. You can export only function entry points (including class member functions) and static data fields. You should include your header both into your dll code and and all applications that use your DLL. The #ifdef MYDLL_EXPORTS has exactly this purpose.
I'm currently writing a program that should be working on both Windows and Linux. The program uses dynamic modules (LoadLibrary/dlopen) to simplify deployment of different functions.
The Linux part works just fine: The main program exports functions and variables with -Wl,--export-dynamic so the modules can access them, and the modules can be compiled with gcc's -shared option without the requirement to resolve all symbol dependencies when linking.
With Windows (using MSVC 2010), this seems not to work. I'm exporting functions and variables from the main program using __declspec(dllimport), but I am not able to access functions and variables from the main program because linking fails (unresolved external, LNK1120).
How to deal with this? Thank you.
Edit (code sample):
core-file.cpp
#include "core-file.hpp"
Cls_A cls_instance;
void Cls_A::do_something() {
while(0);
}
core-file.hpp
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
class TEST_API Cls_A {
public:
void do_something();
};
extern Cls_A cls_instance;
module.cpp
#include "core-file.hpp"
TEST_API int my_init_function() {
cls_instance.do_something();
return 0;
}
__declspec(dllimport) is for when you're compiling the the program that uses the DLL. When you compiling the actual DLL, you want to use __declspec(dllexport).
Your use of these must be consistent. The typical idiom is to define a macro that will use dllimport and dllexport based on the presence of a macro. In the project the builds the DLL, you define the macro that means to export the functions, and in other projects you don't define it, which means to import them:
#ifdef PROJECT_NAME_BUILD_DLL
#define DLL_SYMBOL __declspec(dllexport)
#else //PROJECT_NAME_BUILD_DLL
#define DLL_SYMBOL __declspec(dllimport)
#endif //PROJECT_NAME_BUILD_DLL
DLL_SYMBOL void SomeFunction(Type value);
The project that builds the DLL will define PROJECT_NAME_BUILD_DLL; projects that use the DLL which include this header do not define this.
On Windows, when you want to link against exported symbols you have to remember to specify all the import libraries that were generated when you linked the modules whose symbols you want to import. (You can just leave the symbols unresolved on Linux because the executable format is different and it's possible to defer symbol resolution to load time.)
How can I remove this link warning? You can see code segment that causes this warning.
static AFX_EXTENSION_MODULE GuiCtrlsDLL = { NULL, NULL };
//bla bla
// Exported DLL initialization is run in context of running application
extern "C" void WINAPI InitGuiCtrlsDLL()
{
// create a new CDynLinkLibrary for this app
new CDynLinkLibrary(GuiCtrlsDLL);
// nothing more to do
}
warning C4273: 'InitGuiCtrlsDLL' : inconsistent dll linkage
I have also export and import definitions, like:
#ifdef _GUICTRLS
#define GUI_CTRLS_EXPORT __declspec(dllexport)
#else
#define GUI_CTRLS_EXPORT __declspec(dllimport)
#endif
The purpose of the preprocessor statements:
#ifdef _GUICTRLS
#define GUI_CTRLS_EXPORT __declspec(dllexport)
#else
#define GUI_CTRLS_EXPORT __declspec(dllimport)
#endif
is to make sure that the header file declares the class or function as __declspec(dllexport) in the .dll where it is defined, and as __declspec(dllimport) for any other .dll that might want to use it.
For this to work, _GUICTRLS must be defined when compiling the exporting .dll, and not defined for any other .dll. Generally you would expect _GUICTRLS to be defined in the project properties, under C/C++ -> Preprocessor -> Preprocessor Definitions.
The compiler error you are seeing usually happens because either _GUICTRLS is not defined for the project that is doing the export, or it is defined for multiple projects, usually resulting from cutting an pasting from one project to another. You will also see this if _GUICTRLS is defined in a header file that is included in multiple projects.
There are multiple possibilities:
1) static AFX_EXTENSION_MODULE GuiCtrlsDLL = { NULL, NULL };
You use AFX_EXTENSION_MODULE. This means that you are implementing an MFC extension DLL. For such extension dlls you have to define the preprocessor _AFXEXT. Set this in the C++ compiler settings of your Visual C++ project
see:
How To Use _declspec(dllexport) in an MFC Extension DLL: http://support.microsoft.com/kb/128199
AFX_EXTENSION_MODULE Structure: http://msdn.microsoft.com/en-us/library/sxfyk0zk.aspx
TN033: DLL Version of MFC: http://msdn.microsoft.com/en-us/library/hw85e4bb.aspx
2) It is likely that you have a duplicated definiton/declaration.
In addition to reading the warning message, pay attention to where it occurs if you have multiple projects as part of a workspace.
I wasted time looking for a problem in my DLL which was compiling and linking correctly. The workspace was also building the main application and my error was that I had inadvertently included a new (DLL) source file into the build file list of the application itself.
The main program requires the DLL header mynewdll.h to import things but does not require the source file mynewdll.cpp. (The code is brought in at run time with a DLL.) I have a habit of including header and code files into projects as a pair, and this is where I had gone wrong.
I would have detected the error much sooner if I had been alert and noticed that the DLL project linked with no errors and it was the main program that complained!
My DLL source code and project was error free and it was only the way I tried to build my executable that was faulty.
That warning is usually caused by a duplicate definition of a function with different use of dllimport. Are you sure you didn't do this?
[ CMake inconsistent dll linkage ]
I encountered the following issue + solution with the __declspec(dllexport) + __declspec(dllimport) :
# # #CMakeLists.txt
add_defintions(-DMYLIB=1)
# The above was the solution...
# (MYLIB is used in the standard ifdef + define MYLIB_EXPORT syntax)
# Below: seems to get overruled by other directory's headers:
set_source_files_properties( file1.h file2.h COMPILE_FLAGS "-DMYLIB=1")
This was annoying because a number of sources say to use the 'set source file properties' command to get better granularity but the doc is not clear on what happens to file1.h's declares when included from a different directory... better stick with add_definitions( -DMYLIB=1 ) for now!
To catch this problem: in your Foo.cpp file:
#include "export.h"
#if defined(MYLIB)
#if defined(OTHERLIB)
static_assert(0,"error, check your definitions!");
// OTHER depends on MY; can't have both of these flags being set!
#endif
#endif
struct OTHER_EXPORT foo
{
};
See that you are not defining the exported symbols in a different project. Also clean all the intermediate files by hand and recompile.
To elaborate the answer of damian with an example. I read it but didn't understand at first glance.
You have a shared library with a source file compiled in that contains the function. In a new project you use the library and in addition you compile also the source file to use the function (I forgot that it is already in the library). Within the library the functions label is exported, within the additional compiled source file the functions label is marked to be imported. That's the conflict.
In my case, error C4273 was caused by trying linking to .lib file from a DLL dynamic load tester app in Qt5 by msvc2017_64 toolchain. Removing the reference to .lib file by changing LIBS setting in .pro file have the problem solved.