why do we have to declarer a class name in C++ like:
class MDT_DECL Transfer{
// declaration goes here
};
? What's the reason for the <DIRNAME>_DECL? I see it's especially used when the code needs to be compiled in Windows
You don't have to. But in windows you have to explicitly state you want the class to export symbols with _declspec(dllexport) (which is probably what that macro expands to).
Related
I have a dll that contains a templated class. Is there a way to export it without explicit specification?
Since the code for templates is usually in headers, you don't need to export the functions at all. That is, the library that is using the dll can instantiate the template.
This is the only way to give users the freedom to use any type with the template, but in a sense it's working against the way dlls are supposed to work.
Are you looking into exporting an instantiation of a template class through a dll? A class along the lines:
typedef std::vector<int> IntVec;
There is some discussion how to do this on:
http://support.microsoft.com/kb/168958
Another approach is to explicitly exporting each function you are interested in through a wrapper class working against this template instance. Then you won't clutter the dll with more symbols than you are actually interested in using.
When the compiler finds an instantiation of a template class, like MyTemplate<int>, then it generates the code for the template specialization.
For this reason, all the template code must be placed in an header file and included where you want to use it.
If you want to 'export' your template class, just place your code in an header file and include it where it's needed.
In your export control file.
#ifdef XXXX_BUILD
#define XXXX_EXPORT __declspec(dllexport)
#define XXXX_EXTERN
#else
#define XXXX_EXPORT __declspec(dllimport)
#define XXXX_EXTERN extern
#endif
where XXXX_BUILD is a symbol defined in your project.
To get your class exported.
XXXX_EXTERN template class XXXX_EXPORT YourClass<double>;
Where double is the type you want to instantiate the class with.
https://support.microsoft.com/en-us/help/168958/how-to-export-an-instantiation-of-a-standard-template-library-stl-clas
class is defined using Macro. Not sure what is the significance of MACRO DEBUG_API here. [I understand #define is used to
turn on or off some specific set of code.] But below code I cannot grasp. any explanation would be appreciated
#define DEBUG_API
class DEBUG_API Cdebug
{
public:
/*
constructor, methods here.
*/
};
When defining this macro, you can choose attributes that will be applied to the class. These can be standard or compiler-specific attributes.
Your particular example is most probably an instance of the usual pattern for DLL headers under MSVC. Depending on a compile-time switch, DEBUG_API will be set to either :
__declspec(dllexport), which will make MSVC generate a .lib file containing the class' thunk; this is used when compiling the library as a DLL;
__declspec(dllimport), which will make MSVC link against the thunk generated above; this is used when linking with the DLL;
Nothing, which won't alter the behaviour of the class. This is used to link statically against the library.
Have read this thread in stackoverflow: Strange class declaration
, but still confused with below code in foo.h:
class Foo CHECKLEAKDCL {
I am sure that Foo should be the class name, since there are constructor and deconstructor which can imply this.
I cannot see any macro definition related with CHECKLEAKDCL in this .h file.
also I am confused with the answer for Strange class declaration , which saying that:
Q_CORE_EXPORT isn't an identifier. It's a platform-dependent macro,
and it's used to signal a class that's intended to be used across
library boundaries.
Can anyone give some more explanation of this?
UPDATE:
found this line in a .h file, which is included in foo.h:
#define CHECKLEAKDCL : private CheckLeak
so the class declarition should be :
class Foo : private CheckLeak {
So Foo is extending CheckLeak, right?
If you compile for windows (using Visual Studio), highly possible it will be evaluated to one of the Microsoft specific linkage identifiers, dllexport or dllimport :
https://msdn.microsoft.com/en-us/library/81h27t8c.aspx
It is used when you create a class which will be exported from a DLL or used from a DLL in an application, and dependig of this it's either evaluated to dllexport (DLL exporting the class) or dllimport (Application importing the class).
If you compile with GCC possibly it will evaluate to one of the gcc _-attribute__s. Such as __attribute__ ((visibility ("default"))) (https://gcc.gnu.org/wiki/Visibility)
These extensions to the core C++ are provided by compilers to make certain tasks more easily achievable (https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Extensions.html)
EDIT
After you updated the answer ... well, obviously you have a private inheritance from a class. But please note, this is a terrible macro you have there because
#define CHECKLEAKDCL : private CheckLeak
adds an : in your class declaration so you cannot use that symbol anymore to inherit from base classes.
I'd recommend that you get rid of that macro altogether, if you cannot, do not use it, it will confuse your code.
We cannot tell exactly what it is, as we have even less information than you do.
Normally, I have seen such macros resolve to export macro, for the library.
That is, the value of it should be defined as dllexport, dllimport or extern (depending on platform). When that is the case though, the macro appears before the class name.
Considering the macro appears after the class name, it can only resolve to a base class, or list of base classes, or an empty macro.
If you have the documentation, search for a base class that tracks or reports it's address to a memory tracker on construction and destruction.
Then, the code base should be compiled using a macrodefinition similar to this:
#define CHECKLEAKDCL() : private MemoryTrackingBaseClass
(where MemoryTrackingBaseClass is the class I mentioned above - according to your edit, CheckLeak).
If you want to simply compile, try using:
#define CHECKLEAKDCL()
Edit (addressing your update)
So Foo is extending CheckLeak, right?
Only when you want to check your application for leaks, using whatever CheckLeak implements.
In a production environment (after you use the definition inheriting from CheckLeak), you should probably define CHECKLEAKDCL as an empty macro (for speed).
As you've discovered, CHECKLEAKDCL is a macro that expands to the three tokens : private CheckLeak. Presumably CheckLeak is a class that adds some leak checking diagnostic behaviour to classes which inherit from it.
In general, this sort of obfuscation is not very helpful. Depending on the properties of CheckLeak, this macro might have unintended side effects, such as turning what appears to be a standard layout class into a non-standard layout class.
It would also be hard to add CHECKLEAKDCL to a class that wanted to inherit from another class for any other reason. (Are you supposed to class Foo CHECKLEAKDCL, public OtherBase ?)
Personally, if given the chance to improve this project I'd favour replacing this macro with its actual expansion in this case.
I'm trying to understand some C++ code which has the following class syntax:
class Q_MONKEY_EXPORT BasePlugin : public QObject
{
// some code comes here
};
I cannot understand the syntax class Q_MONKEY_EXPORT BasePlugin. To me it looks like if there are two names for the class. What exactly does this kind of syntax mean in C++?
Q_MONKEY_EXPORT is most likely a #define somewhere. Defines like that are sometimes required, for example when the class is in a library and needs to be exported when the header file is included from somewhere else. In that case, the define resolves to something like __declspec(dllexport) (the exact syntax will depend on the tools you are using).
That's most probably a preprocessor directive telling the compiler the symbol is to be exported.
It's probably defined as:
#define Q_MONKEY_EXPORT _declspec(dllexport)
which will cause your class to be exported to the dll.
The full declaration will be expanded, before compilation, to:
class _declspec(dllimport) BasePlugin : public QObject
{
// some code comes here
};
EDIT:
As David Heffernan pointed out, macros like these are generally used to let the compiler know whether it needs to import or export the symbols. Usually defined as dllimport for outside modules and dllexport when building the module. I doubt that's the case here, since the name suggests exporting, but it's best to check the documentation or actually go to the definition.
Q_MONKEY_EXPORT is a macro (all upper case is convention for macro) that typically resolves to something like __declspec(dllexport) when you are building the DLL and resolves to __declspec(dllimport) when you are using the DLL.
You can find out exactly what it is by reading your include files.
I have a dll that contains a templated class. Is there a way to export it without explicit specification?
Since the code for templates is usually in headers, you don't need to export the functions at all. That is, the library that is using the dll can instantiate the template.
This is the only way to give users the freedom to use any type with the template, but in a sense it's working against the way dlls are supposed to work.
Are you looking into exporting an instantiation of a template class through a dll? A class along the lines:
typedef std::vector<int> IntVec;
There is some discussion how to do this on:
http://support.microsoft.com/kb/168958
Another approach is to explicitly exporting each function you are interested in through a wrapper class working against this template instance. Then you won't clutter the dll with more symbols than you are actually interested in using.
When the compiler finds an instantiation of a template class, like MyTemplate<int>, then it generates the code for the template specialization.
For this reason, all the template code must be placed in an header file and included where you want to use it.
If you want to 'export' your template class, just place your code in an header file and include it where it's needed.
In your export control file.
#ifdef XXXX_BUILD
#define XXXX_EXPORT __declspec(dllexport)
#define XXXX_EXTERN
#else
#define XXXX_EXPORT __declspec(dllimport)
#define XXXX_EXTERN extern
#endif
where XXXX_BUILD is a symbol defined in your project.
To get your class exported.
XXXX_EXTERN template class XXXX_EXPORT YourClass<double>;
Where double is the type you want to instantiate the class with.
https://support.microsoft.com/en-us/help/168958/how-to-export-an-instantiation-of-a-standard-template-library-stl-clas