This question already has answers here:
Macros in the middle of a class or function declaration
(4 answers)
Closed 6 years ago.
I found the following code:
class BOOST_FILESYSTEM_DECL path
{
};
Usually a class is defined this way:
class Baloon
{
};
How can I have two terms in the class declaration? Does somebody knows what BOOST_FILESYSTEM_DECL is used for (boost library)?
If you take a look at how it is defined, all will be clear:
#ifdef BOOST_HAS_DECLSPEC // defined in config system
// we need to import/export our code only if the user has specifically
// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
// libraries to be dynamically linked, or BOOST_FILESYSTEM_DYN_LINK
// if they want just this one to be dynamically liked:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)
// export if this is our own source, otherwise import:
#ifdef BOOST_FILESYSTEM_SOURCE
# define BOOST_FILESYSTEM_DECL __declspec(dllexport)
#else
# define BOOST_FILESYSTEM_DECL __declspec(dllimport)
#endif // BOOST_FILESYSTEM_SOURCE
#endif // DYN_LINK
#endif // BOOST_HAS_DECLSPEC
//
// if BOOST_FILESYSTEM_DECL isn't defined yet define it now:
#ifndef BOOST_FILESYSTEM_DECL
#define BOOST_FILESYSTEM_DECL
#endif
As you can see, it is a macro. It expands to __declspec(dllexport) or __declspec(dllimport) or empty, depending on other macros. See this answer for more details about declspec specifier. In short, it is platform specific feature that is needed for dynamic linking.
It's actually a macro that evaluates to either __declspec(dllimport) or __declspec(dllexport), and it's basically being used by the Boost libraries to tell the compiler to export (for their own code) or import (for external code).
It is a macro; see here for the definition.
It controls the exposition of the class from the shared library (dll); basically it will land up being a __declspec() (or similar depending on the platform) for either the dllexport when building boost, or dllimport when used in client code.
The BOOST_FILESYSTEM_DECL is probably a macro, look for the declaration:
#define BOOST_FILESYSTEM_DECL
to see what it's mean.
Related
This question already has answers here:
Question on DLL Exporting/Importing and Extern on Windows
(2 answers)
Closed 3 years ago.
I usually see the C++11 keyword using as a type declaration.
I want to make that type visible for the users of my shared library (dll).
So (for windows) I export it with __declspec(dllimport).
__declspec(dllimport) using History = std::list<Event>; //this code is wrong
But I don't know where to put it. I get only errors.
__declspec(dllimport) is not a part of a type, so you cannot put it in using declaration.
A customary way is: #define IMPORT __declspec(dllimport) and put IMPORT in front of each function prototype. It is also possible to use conditional compilation to define IMPORT as __declspec(dllexport) inside the DLL.
This question already has answers here:
What is this macro for at the beginning of a class definition?
(3 answers)
Closed 7 years ago.
When looking at source code for libraries in C++ I often see things like this:
#define API_MACRO
class API_MACRO className
{
//Class stuff
};
In addition I see things like the following with method signatures:
void API_MACRO functionName();
So my question is what is this for and what is this practice called? I tried looking it up online but found nothing. It doesn't seem to offer any benefit or practical use...especially since these functions and classes are already wrapped up inside of namespaces.
How do you make your function or class show up for public use in a Unix shared library or a Windows DLL?
Each one has its own method. Luckily they are similar enough that a macro can handle it.
For GCC you want
#define DLLEXPORT __attribute__((visibility("default")))
For Windows MSVC you want
#define DLLEXPORT __declspec( dllexport )
And if you are linking to a DLL in Windows you need the definitions to be marked
#define DLLEXPORT __declspec( dllimport )
Those lines above were copied from a project of mine and API_MACRO may be a better name, because DLLEXPORT doesn't make a lot of sense when importing.
The API_MACRO is conditionally defined. Typically in this usage, it is defined as __declspec(dllimport) or __declspec(dllexport), or nothing at all when not using MSVC's dynamic linking language extension for whatever reason.
Thus, the definition would usually be found in the build system, which determines whether it's being built under Windows as consuming or building the DLL.
I am reading a C++ header file, in which there writes:
class CLASSEXPORT skExecutable : {.....}
A comment says that CLASSEXPORT is a macro expansion and then I find where CLASSEXPORT is defined.
#define CLASSEXPORT
And that's all..I feel confused about this..What does CLASSEXPORT represent in this sense? And how to understand the class skExecutable?
In your case, CLASSEXPORT is expanded to nothing (probably because it is not needed to expand it into something meaningful in your exact configuration), so your class will just be a class skExecutable {<...>};. This approach is commonly used for import/export directives, e.g. in the following snippet an appropriate directive will be places depending on whether COMPILING_DLL macro is defined:
#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
class DLLEXPORT MyClass
{
};
Just to clear some stuff up: CLASSEXPORT is a macro. Macro expansion is a process, performed prior to compilation, during which all macros are replaced with whatever they are defined as.
In your case, I suspect that CLASSEXPORT is there to allow all classes that are declared in that way to be exported to some kind of shared library if the need arises in the future. Then that CLASSEXPORT would be defined as something like
#define CLASSEXPORT __declspec(dllexport)
and you could use skExecutable directly from a shared library.
Why does the apache source have:
#define AP_MODULE_DECLARE(type) type
What is the advantage of using, for example, this form:
AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config);`
vs
void ap_add_per_dir_conf(server_rec *s, void *dir_config);
Thanks.
Note that other definitions are possible for those macros. include/ap_config.h has the following (with some indentation added by me):
#if !defined(WIN32) || defined(AP_MODULE_DECLARE_STATIC)
...
# if defined(WIN32)
# define AP_MODULE_DECLARE(type) type __stdcall
# else
# define AP_MODULE_DECLARE(type) type
# endif
...
#else
...
# define AP_MODULE_DECLARE(type) __declspec(dllexport) type __stdcall
...
#endif
Here, AP_MODULE_DECLARE is used to add __stdcall (which specifies a particular calling convention) and/or __declspec(dllexport) (which is related to exporting the function as part of the interface of a shared library).
Note that e.g. the __declspec(dllexport) won't be added if AP_MODULE_DECLARE_STATIC is defined. My guess (which might not be entirely accurate as I'm not familiar with this code) is that it's related to linking a module as a static library, in which case __declspec(dllexport) wouldn't make sense.
If you're wondering what "dso" stands for in the comments in that file, it's for dynamic shared object. It's basically a shared library, though Apache seems to reserve the term shared library for things that aren't loaded at runtime using dlopen(3).
I found this in Ogre Framework
class _OgreSampleClassExport Sample_Character : public SdkSample {
...
...
and it's define like this
#define _OgreSampleClassExport
Why we want to have this macro variable?
Presumably so a special qualifier, such as __declspec(dllexport), could be added to such classes by modifying (or conditionally defining) the define:
#define _OgreSampleClassExport __declspec(dllexport)
It's to allow for future exports. Ogre may just strictly be a statically linked library at the moment, but if the authors ever decide to support dynamically-linked libraries (aka shared libraries on some platforms), they will need to write code like:
class
#ifdef EXPORTING
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
Sample_Character [...]
... and that's just for MSVC. Normally they'd have to go through the effort to do this to Sample_Character and all other classes they provide through their library. Making a single macro to be defined later is much easier as they'll only need to do this in one place.