I try to make simple dll project in Visual Studio 2013 like in http://www.itcsolutions.eu/2009/12/10/how-to-create-a-dll-dynamic-link-library-in-c-as-visual-studio-2008-project/
But when i try to build solution it falls with an error:
error LNK1104: can not open file "D:\prj\dlltest1\Debug\dlltest1.lib" D:\prj\dlltest1\ConsoleApplication1\LINK ConsoleApplication1
But dlltest1 is dll-project. Why there is an .lib file?
Updated: The reason why no libs are generated because you have no symbols exported. I just checked your code.
You should have a *.h file define exported symbols like this.
#ifdef WIN32PROJECT1_EXPORTS
#define WIN32PROJECT1_API __declspec(dllexport)
#else
#define WIN32PROJECT1_API __declspec(dllimport)
#endif WIN32PROJECT1_API int fnWin32Project1(void);
When you created a DLL project, it has some exported symbols other project can use. These symbols' name and offset are stored in *.lib file. *.lib file is created with *.dll files, both of them are put in the output directory.
In the link stage of you ConsoleApplication, the linker try to find the symbols from all your referenced libs (defined in project property) and store these symbols' offset and source dll in output exe file.
You can change the libs settings in Property->Linker
Wikipedia says:
DLL compilation will produce both DLL and LIB files. The LIB file is used to link against a DLL at compile-time; it is not necessary for run-time linking.
The code within your application determines whether compile-time or run-time linking is required:
If you access your DLL functions like
__declspec(dllimport) someFunction(int firstArg, int secondArg)
then your compiler will require both the .dll and the .lib file for linking to the shared library, but during execution, only the .dll will be required.
If you however make use of the DLL functions LoadLibrary, GetProcAddress and FreeLibrary, the .lib will not be required for linking.
Related
I've looked through full 14 pages list of similar problems but didn't find my case.
I have VS2017 c++ solution which has two projects DLL and EXE. EXE projects includes DLL header to import function from it.
The problem is that linker can't find dllproject.lib file. I tried to add it to Linker -> Input -> Additional Dependencies but didn't help because linker failed to find that lib file and it exists in the output folder.
Then I used
#pragma comment( lib, "C:\\FULL_PATH\\dllproject.lib")
And this time helped. But the problem is my local absolute path to the lib. I suppose I can somehow configure that in the project settings, but all my attempts failed.
In the DLL header file I have the block (was advised in other answers).
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
Please help.
Adding a library to your project is a two step process.
You add the library name to Linker/Input/Additional Dependencies and you add the library folder to Linker/General/Additional Library Directories.
Then of course you have the potential problem of your program failing to find your DLL, but that's another question.
I have a simple class (the analog clock from the Qt examples) that I want as a test to compile into a shared library. So what I want in the end is to have a .dll file and a .lib file.
What I did was simply create a new project, add the analog clock header and source file and then configure TEMPLATE = lib in the pro file.
Yet this only creates a .dll file and the article I found on the docs is not very helpful.
Does anyone know how can I solve this, and end up with both the dll and lib files?
EDIT 1
After doing this
#if defined(TEST)
#define AnalogClockPlug Q_DECL_EXPORT
#else
#define AnalogClockPlug Q_DECL_IMPORT
#endif
and then simply adding AnalogClockPlug in front of my main class and defining TEST in my pro file, qt generated a lib file.
Yet I am not sure I understand why exactly, or even if it is correct.
Q_DECL_EXPORT is just the same (under Windows) as __declspec(dllexport) pragma. It makes all the methods of your class to go to the dll 'exports' table (a special section in dll binary file).
Lib utility just reads the dll exports, and produces what is called 'the import library' - it's not like a usual static lib, containing actual code, but just a bunch of records stating that 'such procedure name' is to be found in 'such dll name'.
If you don't have that pragma, your dll exports table is empty, and lib utility refuses to output empty lib file. That's all.
To make a static library you will also need to add
CONFIG+= staticlib
to the .pro file
I create a set of C++ DLLs and their import libraries in VisualStudio (2013). So far, these were all generated at the same time by linker. My DLLs use symbols from other libraries, which are included as additional dependencies in properties/link edition.
Sometimes, the DLL generation fails because of missing importation libraries, which is fine to me, but in such case there's no generated .lib file either. I would like to generate the import libs (of my DLLs) even if the DLLs cannot be done, in order to allow other projects to rely on the symbols I shall export before I'm able to provide the whole stuff.
I found a workaround through a pre-link event command line, with:
LIB /DEF:(...)\myLib.def /OUT:(...)\myLib.lib $(IntDir)*.obj
This generates exactly what I need, when I do have a .def file.
The problem is, I most often don't have such a .def file but rely on __declspec(dllexport) instructions instead, and in such case I didn't find a way to get a correct result.
I tried:
LIB /OUT:(...)\myLib.lib $(IntDir)*.obj (#1)
This creates a (static ?) lib file, not an import library, not what I need.
LIB /DEF /OUT:(...)\myLib.lib $(IntDir)*.obj (#2)
This fails on error 1104 because of missing (other) import libraries.
What's more puzzling to me is, the command line (#2) fails on libraries that should be here (they are found by the linker, actually). I'm wondering whether I am supposed to provide the complete LINK command line arguments to the LIB command, in which case it would be a no-go.
I'm not much of a specialist of the compilation/link tools, I fear, I'm probably doing pretty wrong stuff...
Does anyone know of a simple way to fulfill my need without using a .def file ? Is there an option in the linker to ask for import library creation from the declared __declspec(dllexport) symbols and generate it even when the DLL cannot link ?
This fails on error 1104 because of missing (other) import libraries.
Edit: oh, I get it. .obj files have /DEFAULTLIB: inside them and lib complains. Use /NODEFAULTLIB
hasunresolved.c:
#pragma comment(lib, "missinglib.lib")
void missingfunc();
__declspec(dllexport)
void dllfunc() {
missingfunc();
}
usedll.c
__declspec(dllimport)
void dllfunc();
int main() {
dllfunc();
return 0;
}
in VS command prompt:
cl -c hasunresolved.c
lib /def /OUT:test.lib hasunresolved.obj
rem this prints: LIB : fatal error LNK1104: cannot open file 'missinglib.lib'
lib /NODEFAULTLIB /def /OUT:test.lib hasunresolved.obj
cl usedll.c test.lib
dumpbin /IMPORTS:test.dll usedll.exe
output:
Dump of file usedll.exe
test.dll
0 dllfunc
As the title says, although I guess what I really mean is "And using them later."
The Setup
I have followed this answer:
https://stackoverflow.com/a/13219631/696407
which creates a very simple dll
#include <stdio.h>
extern "C"
{
__declspec(dllexport) void DisplayHelloFromMyDLL()
{
printf ("Hello DLL.\n");
}
}
and I now have a dll compiled for release:
DllTest.dll
DllTest.exp
DllTest.lib
DllTest.pdb
When I run DllTest.dll through dumpbin, I find this line:
1 0 00001000 DisplayHelloFromMyDLL = _DisplayHelloFromMyDLL
USING THE DLL
To use that function in a new solution, I believe I must
Start a project in a new solution
Add the location of the DLL to the project under
Properties
Configuration Properties
Linker
General
Additional Library Directories
Add the .lib file under
Properties
Configuration Properties
Linker
Input
Additional Dependencies
and, having added the .lib there, the next step is... hvæt?
My code right now:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
while(1)
{
DisplayHelloFromMyDLL();
}
return 0;
}
but that doesn't work.
EDIT: I guess "doesn't work" is vague. The function gets Error: identifier "DisplayHelloFromMyDLL" is undefined
(Side question: Is my function called DisplayHelloFromMyDLL(); or _DisplayHelloFromMyDLL();?)
You need .h for compiler (use with #include, and add the folder to .h file as relative path to Configuration Properties > C/C++ > General > Additional Include Directories). Aside from .lib for linker you also need .dll to actually run the test application.
EDIT: There are two types of DLL's that you can make. First are C-like DLL's, with functions that have signatures as if they are written in C instead of in C++. All Windows DLL's (user32.dll, shell32.dll, version.dll) are built as such. The other are C++ DLL's, with functions that are part of the class. MFC and Standard C++ Libraries are such.
If you want to make a C++ DLL then you have to declare all classes that are part of interface as __declspec(dllexport) in your DLL project and __declspec(dllimport) in all projects that would use DLL. Usually the same file is used for this, but with a macro that is defined accordingly to one or the other. If you create a DLL from Visual Studio project template you would see this code.
Your case is actually the simpler case, as you want C-like DLL. You don't have to fiddle with this __declspec rubbish, but you need one additional .def file in DLL project. This should be the content of the .def file:
LIBRARY MyApi
EXPORTS
DisplayHelloFromMyDLL
Your header file (.h file) should look like this:
#pragma once
#ifndef HELLO_DLL_INCLUDED
#define HELLO_DLL_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
void DisplayHelloFromMyDLL();
#ifdef __cplusplus
};
#endif
#endif // HELLO_DLL_INCLUDED
__declspec(dllimport) tells the compiler that this function (or class) is defined somewhere else, and that linker will find it and link it. __declspec(dllexport) tells the compiler (and linker) that this function (or class) should be exported and be part of DLL interface. If class has neither of those then it's just a class that should be defined in the same project.
To consume your .dll you need two things, a header file and a .lib.
The header file is so that the compiler knows there is a function somewhere with the name DisplayHelloFromMyDLL(). At this point it doesn't matter where it is, just that you've told the compiler it's somewhere. The linker will take care of the where bit.
The .lib file is for the linker. It tells the linker that DisplayHelloFromMyDLL() lives in a .dll, and that (in your case) the name of the dll is DllTest.dll. When your program starts up the Windows loader will use this information to load the .dll into your process and will perform any address fixups to make sure that calling DisplayHelloFromMyDLL() in your application calls the function in your .dll.
You don't actually need the .dll in order to build your executable, only to run it.
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.