Preprocessor Definition Setting: Project Properties ->C/C++ -> Preprocessor - c++

I have a Dll, which I need to statically Link.
This dll eg. DTE.dll is a Third party dll.
My application is facing problem in linking this dll Statically.
I wish to Link this dll ( DteStatic.lib which is newly sent by the third party).
There is a setting in the Project Properties ->C/C++ -> Preprocessor: where I need to add DTE_STATIC.
My question: How do I do Static Linking when I have a dte.lib file.

i think you can give the DteStatic.lib while linking , it will do static linking in case visual studio compilers .

The _ won't create any problem. In my project in Project Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions I have _LIB and _DEBUG.
Edit:
DTE_STATIC is likely some preprocessor definition specific for your library. I don't know anything about DTE_STATIC, but as an example let's look how _DEBUG definition could work.
You could have some code you want to compile only in debug mode. For example this code can write some debug info on the command line, but it's not a good idea to show this info to your customer in release build. This code could look like this:
int x = 4;
x *= -8 << 2;
// ...
#ifdef _DEBUG
printf("DEBUG INFO: %d\n", x);
#endif
// ...
If _DEBUG is not defined the line between if is just omitted. If you set _DEBUG in Preprocessor Definition that line is compiled and executed.
Note: Setting preprocessor definition in Visual Studio is equivalent simply writing #define _DEBUG on the top of your header files.

Related

Scope of a C++ symbol

AFAIK, symbols are useful to prevent multiple parsing. If both a.h and b.h include c.h, a
#ifndef C_H
#define C_H
...
// c.h definition would go here
...
#endif
will prevent c.h from being "parsed" (I believe it's not the right word) more than once.
However, I have seen something like
#ifdef WIN32
...
in other people's code. That symbol must have been defined somewhere else because a search for
#define WIN32
in the whole project returns empty. My question is: where are these symbols actually defined? Does the OS keep something similar to a pool of symbols that different programs can use to query for OS or other processes properties?
There are two options where those which are not in the code itself can originate from:
The compiler suite itself sets it as a default when you start compiling your code.
You give the compiler (or preprocessor, to be exact) a list of those definitions when you compile the code (or your IDE project preferences do, when you are using an IDE. For example, in Visual Studio 2013 you will find those when you open Project > Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions).
In general, those definitions are not only used for the reason you describe (as include guards), but also to enable or disable code based on the platform you develop for - for example, you can have code branches only compiled for windows, or only if you are using a 64 bit compiler.
You might want to take a look at some predefined compiler macros
Microsoft
AFAIK this is part of the compiler you use.
The Microsoft C++ compiler internally defines some macros such as WIN32, that's why it's not defined in any particular header. So when you build a source file with VC++ the stuff in inside #ifdef WIN32 gets compiled, but not on say Linux gcc.
Also your nomenclature is a bit off -- these are called preprocessor macros, not symbols. The names of the variables, functions, etc in your code are symbols.
Each compiler has a list of defined macros. MSVC defines WIN32 when compilation target is 32-bit Windows.

c++ import functions from dll - my dll doesn't export lib

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.

How can I manage building library projects that produce both a static lib and a dll?

I've got a large visual studio solution with ~50 projects. There are configurations for StaticDebug, StaticRelease, Debug and Release. Some libraries are needed in both dll and static lib form. To get them, we rebuild the solution with a different configuration. The Configuration Manager window is used to setup which projects need to build in which flavours, static lib, dynamic dll or both.
This can by quite tricky to manage and it's a bit annoying to have to build the solution multiple times and select the configurations in the right order. Static versions need building before non-static versions.
I'm wondering, instead of this current scheme, might it be simpler to manage if, for the projects I needed to produce both a static lib and dynamc dll, I created two projects. Eg:
CoreLib
CoreDll
I could either make both of these projects reference all the same files and build them twice, or I'm wondering, would it be possible to build CoreLib and then get CoreDll to link it to generate the dll?
I guess my question is, do you have any advice on how to structure your projects in this kind of situation?
Thanks.
Make a copy your original project file in explorer as CoreLib.vcxproj (in case of other VS check the appropiate extension)
Add CoreLib.vcxproj as an existing project to your solution and save your solution.
Go to the properties->Configuration Properties->General of CoreLib.
Select all Configurations (left upper corner).
Change property Configuration type to static library.
Change property Target Extension to .lib .
Append to property Intermediate directory for example \Lib\ .
Go to the properties->Configuration Properties->C/C++->Preporcessor
Select Debug Configuration (left upper corner).
Now edit the property Preprocessor Definitions and change the line _USRDLL into _USRLIB
Select Release Configuration (left upper corner).
Now edit the property Preprocessor Definitions and change the line _USRDLL into _USRLIB
In your header-file you should have something like the following:
#ifdef MyDll_EXPORTS
#define MyDll_API __declspec(dllexport)
#else
#define MyDll_API __declspec(dllimport)
#endif
change it into something like the following :
#ifdef MyDll_EXPORTS
#ifdef _USRLIB
#define MyDll_API
#else
#define MyDll_API __declspec(dllexport)
#endif
#else
// Here must deploy your own logic whether static or dynamic linking is used.
// read my comment below
#define MyDll_API __declspec(dllimport)
#endif
Now your Build generates your original dll and import lib as well as a new static lib !
Maybe you could check what a build system like CMake produces for this case. I'm guessing it will generate two projects for each case. But by creating the solution this way it could possibly save you a lot of work.

Using preprocessor directives to define command line options

If I wanted to add, let's say, a new .lib to the build only if a particular #define was set, how would I do that?
In the MSVC++ 2008 "Property Pages", you would simply add: Config Properties -> Linker -> Input -> Additional Dependencies, but I would like it if something like #define COMPILE_WITH_DETOURS was set, then the particular library would be added to the dependencies, otherwise it would be removed.
You can set some linker options by using #pragma comment in one of your source files.
For example, to link against a 'detours.lib' library only if COMPILE_WITH_DETOURS is defined, you can use:
#ifdef COMPILE_WITH_DETOURS
# pragma comment(lib, "detours.lib")
#endif
(this is specific to Microsoft Visual C++ and is not portable)

About inconsistent dll linkage

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.