Preprocessor identifier in front of function declarations in a header file - c++

I was reading a header file and I noticed that the programmer has put a preprocessor identifier in front of the return values of functions in their declarations, as following.
#ifndef SAMPLE_API
#define SAMPLE_API
#endif
...
namespace SampleName
{
SAMPLE_API bool api_function();
...
}
What's the purpose of it and how does it work?
Edit: I am reading imgui.h from the IMGUI project.

By defining SAMPLE_API (on your compiler command line, in your Makefile / IDE environment etc.), you could add something to each function declaration in this header.
If you did not define SAMPLE_API, the first couple of lines...
#ifndef SAMPLE_API
#define SAMPLE_API
#endif
...make sure that SAMPLE_API is "defined away", i.e.
SAMPLE_API bool api_function();
...is preprocessed to...
bool api_function();
...so "nothing happens" (instead of "syntax error" when the compiler runs into SAMPLE_API and does not know what to do with it).
The usual reason for a construct like this SAMPLE_API symbol is to handle symbol export / import when building / using a library for Windows.
You would define SAMPLE_API to...
__declspec(dllexport) when building a library for Windows,
__declspec(dllimport) when using a library for Windows,
...so the symbols for the functions in question get exported / imported as necessary.
There are other things that could be done with such a preprocessor symbol (like deprecating functions, so that the linker will warn if they are being used), or other platform-specific stuff. But I would guess you're looking at dllexport / dllimport plumbing here.

In this particular case it does nothing. (Remember that the preprocessor does little more than trivial copying and pasting).
But, it might be useful in some instances to declare for example, a declspec for exporting a DLL function (in which case it would be #DEFINEd to something less trivial. Needless to say, that kind of thing is not formally part of the C++ standard, but rather is likely exploiting compiler extensions.

Related

Check a __declspec macro in preprocessor

If I have SOME_MACRO which is defined as either __declspec(dllimport) or __declspec(dllexport), is there a way to check at compile time which one is being used?
I.e. something like this:
#if SOME_MACRO == __declspec(dllimport)
// do something
#else
// do something else
#endif
UPD.
Looking at the answers I'm getting I guess I should be more specific in why I need this.
I'm trying to compile a rather big 3rd party library, which has a function declared as dllexport in most parts of their code where it's included. There's however one component in which it's a dllimport.
I need to modify the declaration slighly for the dllimport case. The switch between the two declarations is not very simple, it is a result of quite a deep tree of #ifdef instructions spread across several files. In principle I could dig this info out form these instructions, but to be sure I did it correctly I'd have to try and compile the whole library under several different configurations (each compilation taking a couple hours).
If on the other hand there was a simple way check whether their SOME_MACRO is evaluated to import or export, I could test this on a small program quickly and safely put that inside the library.
You cannot use
#if SOME_MACRO == __declspec(dllimport)
__declspec(dllimport) is not a valid token for a preprocessor expression.
Your best option is to use another preprocessor macro, such as:
// Are we building the DLL?
#if defined(BUILD_DLL)
// Yes, we are.
#define SOME_MACRO __declspec(dllexport)
#else
// No. We are using the DLL
#define SOME_MACRO __declspec(dllimport)
#endif
Now, you can use:
#if defined(BUILD_DLL)
to include conditional code depending on whether you are building the DLL or using the DLL.
Practically speaking, that ends to be a little bit more involved.
Most projects have more than one DLL. BUILD_DLL is not going to work. You will need BUILD_xxx_DLL for each DLL you build. Let's say you have two DLLs, utility and core. and an application that depends on both.
You may also need to create a static library.
You will need something like the following in every public .h file of the utility library.
#if defined(BUILD_UTILITY_STATIC)
#define UTLIITY_EXPORT
#elif defined(BUILD_UTILITY_DLL)
#define UTLIITY_EXPORT__declspec(dllexport)
#else
#define UTLIITY_EXPORT__declspec(dllimport)
#endif
Of course, you don't want to have to repeat the same code in lots of .h files. You will create a .h file that contains the above and #include that in all other .h files.
When building utility.dll, you will need to define BUILD_UTILITY_DLL and leave BUILD_UTILITY_STATIC undefined.
When building utllity.lib (static library), you will need to define BUILD_UTILITY_STATIC and leave BUILD_UTILITY_DLL undefined.
Users of utility.dll will leave BUILD_UTILITY_STATIC as well as BUILD_UTILITY_DLL undefined.
Users of utility.lib (static library) will need to define BUILD_UTILITY_STATIC and leave BUILD_UTILITY_DLL undefined.
You will need a similar file for core.dll and core.lib.
The macro is named by you the DLL creator.
You want a header file that works in export or import mode.
A C/C++ file will be used, to create a program, to build the DLL (export).
Other C/C++ files will be used to call the DLL (import functions).
In the build implementation file a macro, that you name, is defined before the inclusion of the header.
e.g.
#define DLLNAME_BUILD_DLL
#include "dll_header.h"
In the header, if the macro is defined, the mode is set to export. When using the DLL the macro is not defined and the functions are imported.

OSX C++ Export function

I got a large C++ project that uses a makefile on OSX. where I simply want to add an exported function that I can resolve can call. The project needs to be an executeable and not a library. It already exports a bunch of functions but I cannot get my export to work, meaning it's not visible when I run nm on the binary.
I tried to simply add this to the header .h
#define EXPORT __attribute__((visibility("default")))
EXPORT int callme(int test);
I also tried declaring it in the header like
EXPORT int callme(int test) {return 0;}
but then i get a bunch of errors of the symbol already existing in other object files.
Edit: It's a simple C function and I also tried
#if !defined(__cplusplus)
#define MONExternC extern
#else
#define MONExternC extern "C"
#endif
MONExternC int callme (int test);
I'm a bit of novice when it comes to C++ and any insight or help would be much appreciated, thanks.
You have defined (not just declared) a standalone, non-member, non-template, non-inline function in a header. This is exactly the thing you should not be doing. It leads to the sort of errors you describe, and is prohibited by the standard.
You should have only a function ptototype in the header. Move its definition to an exactly one source file.
The visibility attribute only makes sense when building shared libraries. You probably don't need it.

Dynamic libraries; how to fix useless dependencies?

I have a bunch of Dll's in my project, using VStudio 9.0 compiler, pre-compiled headers are used for all my Dll's. The dll's loading process is done by implicit caller (.dll, .lib and header must be supplied).
I typically create a different macro definition file per dll, for instance if my current Dll is called MYMacroDll I add a file _MyMacroDll.h which contains:
#ifndef _MYMACRODLL_H_
#define _MYMACRODLL_H_
#ifdef _WIN32
#ifdef MYMACRODLL_EXPORTS
#define MYMACRODLL_API __declspec(dllexport)
#else
#define MYMACRODLL_API __declspec(dllimport)
#endif
#define MYMACRODLL_CALL __cdecl
#else
#define MYMACRODLL_API
#define MYMACRODLL_CALL
#endif
#endif
I know the code can be simplified but I keep the last defines for portability, at least, that's what I understood...
The pre-compiled header file pch.h, will always include the macro definition file _MyMacroDll.h, this makes things easier to me, 'cause later I can decide whether a new class or function will be interfaced or not. This so far works correct.
The confusion comes from using the dll interfaces in another dll; let's suppose a second dll ImageLoaderDll. This one uses instances or references of one (or several) of the interfaced classes/functions in _MyMacroDll. At first glance I guessed there was no need of including the _MyMacroDll.h, but when compiling the ImageLoaderDll it complains with
error C2470: '_AnInterfaceClassFromMyMacro' : looks like a function definition, but there is no parameter list; skipping apparent body
Then I have to include the _MyMacroDll.h in the pre-compiler header file of the other Dll, my project is becoming really messy and I find more and more useless dependencies.
What am doing wrong? Is there another way of setting up the macro definitions so I can avoid adding it to the client Dll's? Am not an expert regarding software design, but in this situation the more decoupled the better.
Hope my explanation was good enough.
If you are using the DLL interface from MyMacroDll in ImageLoaderDll, then you do have a dependency. ImageLoaderDll should include _MyMacroDll.h, otherwise you can't call its functions correctly. It's exactly the same as including <string.h> when you want to call strlen.

Visual C++: Exporting decorated function name in a def file

I want to export a decorated function name in a def file like this:
LIBRARY Example
EXPORTS
??0__non_rtti_object#std##QAE#ABV01##Z=myfunc #1
The Problem is that the linker strips the function name at the first #-sign and places just
"??0__non_rtti_object" into the export table. My question is now, if there is a way to include
the #-characters as well? I use Visual Studio 2010. Maybe there is someone who can help me.
Thanks in advance, Hannes.
Preamble
You didn't answer my comment about the use of the .DEF file, so I assume you must be unfamiliar with the the dllexport and dllimport qualifiers. With them, there is no need for the .DEF file to export symbols.
If there is a particular need for the .DEF file that invalidate the use of the dllimport/dllexport feature, please ignore the following.
How to use dllimport/dllexport?
In your public header (say, public.hpp), write something like:
#ifdef MY_PROJECT_EXPORTS
#define MY_PROJECT_API __declspec(dllexport)
#else
#define MY_PROJECT_API __declspec(dllimport)
#endif
This way, the macro MY_PROJECT_API will enable the export/import of your symbols. For example, later, in the same public.hpp, you can declare:
// A global variable
MY_PROJECT_API int myGlobalVariable ;
// A function
MY_PROJECT_API void my_function() ;
// A class or struct
class MY_PROJECT_API MyClass
{
public :
int i;
virtual int foo() ;
// etc.
} ;
Then, what you need to do is, in the project options of your library, define the MY_PROJECT_EXPORTS: This way, when you compile your library, the symbols above are declared dllexport, and when someone else includes your public.hpp header, the symbols above will be dllimport
And if your code is cross-platform (dllimport/dllexport is a MS compiler feature), just wrap the defines above around a compiler test. For example:
#ifdef _MSC_VER
// For MS Visual Studio
#ifdef MY_PROJECT_EXPORTS
#define MY_PROJECT_API __declspec(dllexport)
#else
#define MY_PROJECT_API __declspec(dllimport)
#endif
#else
// For other compilers
#define MY_PROJECT_API
#endif
About the .DEF file?
The .DEF file was used before, when exportable C functions were still "the way to go" on Visual Studio.
For strong type safety, C++ decorate its symbols.
The downside is that each compiler has its own decoration scheme (which never bothered me in 12-years of development), and that finding the exact, decorated name of a symbol can't be painful.
But the merits of that is that:
You can now export overloaded/namespaced functions/symbols
the parameter types are part of the ABI, meaning the linker can verify you aren't screwing up or cheating with your types
The dllimport and dllexport features have the following advantages:
it enables the export to be done at source level, instead of using yet another project file
the programmer can now ignore the particular decoration scheme (which usually only interests the linker), all the while profiting from the strong type safety of C++ extended to the linker.
Sources
For more information, see:
__declspec : http://msdn.microsoft.com/en-us/library/dabb5z75.aspx
dllexport, dllimport : http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
Using dllimport and dllexport in C++ Classes : http://msdn.microsoft.com/en-us/library/81h27t8c.aspx

DLL : export as a C/C++ function?

I generated a DLL in Visual from a C++ code. Dependency Walker sees 3 functions exported as C functions.
I made an SCons project to do the generate the DLL, and 2 of the 3 functions are not seen as C functions.
What makes a function seen as a or C++ function, without modifying the code ? It must be in the compilation/linking options, but I didn't find any relevant thing.
The function are prefixed by a macro : AM_LIB_EXPORT
In the .h, I have :
#ifdef _WIN32
#define AM_LIB_EXPORT __declspec(dllexport)
#else
#define AM_LIB_EXPORT
#endif // _WIN32
Thanks.
What makes a function seen as a or C++ function, without modifying the code ?
A function compiled by a C++ compiler is automatically a 'C++-function' and name-mangling occurs to resolve C++ features such as namespaces and overloading.
In order to get 'C' export names, one must use the aforementioned extern "C" qualifier in the function declaration. Alternatively a huge extern "C" { .. } block around the header containing the prototypes.
If this does not solve your issue, its maybe related to dllimport/dllexport. If you #define AM_LIB_EXPORT __declspec(dllexport) in your DLL build, you'll typically also need to make it dllimport for apps linking against your DLL in order for the linker to know where to fetch the symbols from.
Is this a name mangling issue? If you don't use extern "C" around your function declarations, they will get name-mangled.
I found the reason :
The export was also added as additionnal command line option (/EXPORT). In this case, it is exported as a C function. I don't understand why...
I removed this additionnal command line switch.
Thank you all.
I still don't know how to mark a thread as "resolved" ?