learnvst
learnvst

Reputation: 16195

What is this macro for at the beginning of a class definition?

I'm looking through the source of a library and many classes are defined using the following form

class THING_API ClassName 
{
...

Jumping to the macro definition . . .

#ifndef THING_API
 #define THING_API   /**< This macro is added to all public class declarations. */
#endif

What could this be for, and is it a common technique?

Upvotes: 3

Views: 223

Answers (3)

molbdnilo
molbdnilo

Reputation: 66371

Empty macros like that are often used so that other parsers can gather information from the headers.

Apple has the empty IBOutlet macro which the Interface Builder uses to allow you to connect variables to UI items in its GUI, and I think Qt uses the technique for their "moc" precompiler.

Upvotes: 1

Violet Giraffe
Violet Giraffe

Reputation: 33579

It looks to me very much like export macro, which is required when building a shared library (.dll) on Windows. When compiling with MSVC, You have to put __declspec(export) in that spot when building a library, and __declspec(import) when building its client. This is achieved like so:

#if COMPILING_DLL
    #define THING_API __declspec(dllexport)
#else
    #define THING_API __declspec(dllimport)
#endif

Then you define COMPILING_DLL for the library project, and leave it undefined for all other projects. And if you're not on Windows or compiling a static library, you need to define it blank like it's done in your question.

P. S. Other Windows compilers use their own keywords instead of __declspec(dllimport), but the principle remains.

Upvotes: 5

simonc
simonc

Reputation: 42165

One possible use would be to allow you to conditionally mark the class as callable from other libraries in a cross-platform library.

class ClassName

would be callable on Windows using MSVC but you'd need

class __attribute__ ((visibility("default"))) ClassName

for linux using gcc.

In this case, THING_API might be defined like

#ifdef _WIN32
# define THING_API
#else
# define THING_API __attribute__ ((visibility("default")))
#endif

Upvotes: 3

Related Questions