I'm looking at the v4l header files and I found function definitions with the following structure.
#define SOME_VAR
SOME_VAR int somefunc(int i,....);
What is the purpose of using the #define directive in such a way?
Thanks in advance
You can specify a calling convention or a import/export tag. For example Visual Studio you build a DLL and have some functions to export, you can reuse your header file. For compiling the export you use
#define SOME_VAR __declspec(dllexport)
on the import site you write
#define SOME_VAR __declspec(dllimport)
using only one include in both situations reduce the possible errors during updating and bug fixing of the code.
In the case you mentioned above it seems to be for future use as some platforms have other calling conventions (e.g. the pascal calling convention) than others.
Visual Studio uses a similar stub, the macro WINAPI, which is also empty.
Related
#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
How / where do I define COMPILING_DLL ?
Seen here:
what does __declspec(dllimport) really mean?
Sounds like I can't use load-time dynamic linking at all if I can't use the same header?
One another option:
Use the default defined macro local to the project.
You can see the default defined macros local to the project in the below location:
Properties -> C/C++ -> Preprocessor -> Preprocessor Definition.
Example:
Suppose your Project Name is: MyDLL
Default Macro Local to that project: MYDLL_EXPORTS
#ifdef MYDLL_EXPORTS
/*Enabled as "export" while compiling the dll project*/
#define DLLEXPORT __declspec(dllexport)
#else
/*Enabled as "import" in the Client side for using already created dll file*/
#define DLLEXPORT __declspec(dllimport)
#endif
Best place to define COMPILING_DLL=1 is command line of compiler. If you use Visual Studio IDE then it is in Project properties ... C/C++ ... Preprocessor ... Preprocessor Definitions.
__declspec(dllimport) is Microsoft specific extension to C++. Microsoft has excellent online documentation.
In the DLL project, you add a #define (either in a header file or in the project properties) for COMPILING_DLL. As this will not be set for any other project (especially if you name it something better than COMPILING_DLL) then the #if directive will work properly.
You (actually Visual Studio in ideal cases) defines the COMPILING_DLL as an argument to the compiler when you build the DLL. So, it will default to __declspec(dllexport). On the other end, when you USE the DLL's header file, you don't define this, so DLLEXPORT will be evaluated by default to __declspec(dllimport).
If you use CMake to generate your build configuration, you should be able to use
the macro <projectname>_EXPORTS the way you want to use COMPILING_DLL, where projectname was defined with the CMake command project(projectname):
A preprocessor macro, <target_name>_EXPORTS is defined when a shared library compilation is detected.
source
I tested and it works on Windows using the Ninja generator with compiler MSVC from Visual Studio 2015 Express.
Related: CMake adds -Dlibname_EXPORTS compile definition
You can't define function body that way in the header file. It is prohibited by __declspec(dllimport). This specifier can only be specified on function declaration, not definition.
You have to move the function body to a source file.
in header file:
extern DLLEXPORT void test2();
In .cpp file:
void test2()
{
// ...
}
As folks said, don't forget to add COMPILING_DLL to the project preprocessor definitions.
Actually, the real problem is the preprocessor directive.
You should use #ifdef and not #if to test if the variable is really defined (and we don't care about the defined value or if there is any).
NOTE: I know this thread is 1-year old but it still may be useful for somebody who have this problem in the future.
I have seen many c++ header file under MSVC environment like this:
#ifdef somelib_EXPORTS
#define DLLEXPORTS __declspec(dllexport)
#else
#define DLLEXPORTS __declspec(dllimport)
#endif
Where does the <libname>_EXPORTS convention come from ?
Is it a Visual Studio's default macro ? Or is it generated by CMake ?
I can't find any document about this convention.
Where does the _EXPORTS convention come from ?
This is general coding guideline that helps with making sure that a .h file can be #included while building a DLL and by the users of the DLL.
The name DLLEXPORTS is project specific. It can be generated by CMake, qmake, or manually. I don't think Visual Studio can generate them, at least I haven't seen that.
If you have 10 DLLs in your project, you will end up using 10 such macros. For example, you might have UTILITY_DLL_EXPORT, MESSAGING_DLL_EXPORT, KERNEL_DLL_EXPORT, etc.
#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
How / where do I define COMPILING_DLL ?
Seen here:
what does __declspec(dllimport) really mean?
Sounds like I can't use load-time dynamic linking at all if I can't use the same header?
One another option:
Use the default defined macro local to the project.
You can see the default defined macros local to the project in the below location:
Properties -> C/C++ -> Preprocessor -> Preprocessor Definition.
Example:
Suppose your Project Name is: MyDLL
Default Macro Local to that project: MYDLL_EXPORTS
#ifdef MYDLL_EXPORTS
/*Enabled as "export" while compiling the dll project*/
#define DLLEXPORT __declspec(dllexport)
#else
/*Enabled as "import" in the Client side for using already created dll file*/
#define DLLEXPORT __declspec(dllimport)
#endif
Best place to define COMPILING_DLL=1 is command line of compiler. If you use Visual Studio IDE then it is in Project properties ... C/C++ ... Preprocessor ... Preprocessor Definitions.
__declspec(dllimport) is Microsoft specific extension to C++. Microsoft has excellent online documentation.
In the DLL project, you add a #define (either in a header file or in the project properties) for COMPILING_DLL. As this will not be set for any other project (especially if you name it something better than COMPILING_DLL) then the #if directive will work properly.
You (actually Visual Studio in ideal cases) defines the COMPILING_DLL as an argument to the compiler when you build the DLL. So, it will default to __declspec(dllexport). On the other end, when you USE the DLL's header file, you don't define this, so DLLEXPORT will be evaluated by default to __declspec(dllimport).
If you use CMake to generate your build configuration, you should be able to use
the macro <projectname>_EXPORTS the way you want to use COMPILING_DLL, where projectname was defined with the CMake command project(projectname):
A preprocessor macro, <target_name>_EXPORTS is defined when a shared library compilation is detected.
source
I tested and it works on Windows using the Ninja generator with compiler MSVC from Visual Studio 2015 Express.
Related: CMake adds -Dlibname_EXPORTS compile definition
You can't define function body that way in the header file. It is prohibited by __declspec(dllimport). This specifier can only be specified on function declaration, not definition.
You have to move the function body to a source file.
in header file:
extern DLLEXPORT void test2();
In .cpp file:
void test2()
{
// ...
}
As folks said, don't forget to add COMPILING_DLL to the project preprocessor definitions.
Actually, the real problem is the preprocessor directive.
You should use #ifdef and not #if to test if the variable is really defined (and we don't care about the defined value or if there is any).
NOTE: I know this thread is 1-year old but it still may be useful for somebody who have this problem in the future.
What does it mean exactly when I define a class this way in C++ project:
class THIS_DLL_NAME class_name{
...
}
thanks!
As Basile and Hans stated in the comments above, THIS_DLL_NAME will be a macro that conditionally expands depending on whether you are building the library itself, or code that just uses that library.
(BTW, I'm assuming you're on Windows here, due to the DLL terminology.)
THIS_DLL_NAME can expand to either __declspec(dllexport) or __declspec(dllimport). When the header file is included in the .cpp files that you're compiling into THIS_DLL.dll, the compiler needs to see __declspec(dllexport) in order to generate the proper entry points to export them from the DLL.
When your class header is included in code that is using THIS_DLL.dll, the compiler needs to see __declspec(dllimport) in order to generate the right code to import the symbol (and resolve it at runtime).
You can read up on more of the details straight from Microsoft in this article - Importing and Exporting (MSDN).
I've managed to get input hooks working, but now I'm kinda lost with putting them into a library.
I have a simple header with INPUTHOOK_EXPORTS defined in the IDE, so the dll exports (Visual Studio).
#pragma once
#ifdef INPUTHOOK_EXPORTS
#define INPUTHOOK_API __declspec(dllexport)
#else
#define INPUTHOOK_API __declspec(dllimport)
#endif
INPUTHOOK_API void InstallInputHook();
INPUTHOOK_API void RemoveInputHook();
and of course:
The cpp file
The thing is, when I try to compile this library, I get two unresolved externals, one for SetWindowsHookEx and for UnhookWindowsHookEx respectively. Why these two functions are not available, while others are and without any problem? As far as I see, I do have the includes right.
Thank you
SetWindowsHookEx is a macro that should turn into SetWindowsHookExA' for ascii orSetWindowsHookExWfor wchar. Similary forUnhookWindowsHookEx` .
The error reported should be specific to which function is missing - A or W - which seems to indicate for some reason the macro is not in place.
You seem to be missing winuser.h in the cpp, however this or an equivalent may be in the pre-compiled stdafx.h header.
You need to include user32.lib while building (linking) your library (normally in the default included libs).
From MSDN topic LowLevelKeyboardProc:
This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.