How do I use FTGL's C API from C++ code in Visual Studio 2010?
FTGL uses #ifdef __cplusplus checks to export C and C++ APIs from the same header files.
I tried this:
#ifdef __cplusplus
#undef __cplusplus
#include <FTGL/ftgl.h>
#define __cplusplus
#else
#include <FTGL/ftgl.h>
#endif
But VS2010 isn't having it:
warning C4117: macro name '__cplusplus' is reserved, '#undef' ignored
warning C4117: macro name '__cplusplus' is reserved, '#define' ignored
The macro __cplusplus is a reserved macro, and should be defined automatically by your compiler if you're compiling as C++ code (and not defined otherwise). You shouldn't have to #define it manually, and that's why your compiler throws an error.
How do I use FTGL's C API from C++ code in Visual Studio 2010?
You don't.
The makers of FTGL apparently don't want C++ users to use the C API. So they don't let them.
The __cplusplus macro is a part of the C++ language; it cannot be undefined. Or defined. Or redefined. And since that's what FTGL keys off of, there's no way to trick it into compliance.
The only way to avoid this is to edit FTGL itself.
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.
Are there preprocessor macros defined in the gcc and g++ compilers so that if I want to make my C code link to the C standard library or the C++ standard library? Something like:
someFile.c
#ifdef __CPP__
#include <c++ library include>
#else
#include <c library include>
I'm sure there are but a quick Google search didn't point me to right away and I'm sure someone is going to just post duplicate question, but in any case, please point me in the right direction.
In c++ you can you
#ifdef __cplusplus
eg if c++ code you want certain piece of code to be handled by compiler as c code you need to put that block in
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
I'm not sure if there are #defines specific to GCC, but the C++ standard defines the symbol __cplusplus. If that exists, then you are on a C++ compiler.
As pointed out by the other answers, testing for the definition of the __cplusplus predefined macro will work:
__cplusplus denotes the version of C++ standard that is being used, expands to
value 199711L (until C++11), 201103L (C++11), 201402L (C++14), or
201703L (C++17).
There is also a GCC specific macro which may be useful to you, __GNUG__. As outlined in the GCC documentation:
__GNUG__
The GNU C++ compiler defines this. Testing it is equivalent to testing
(__GNUC__ && __cplusplus).
The linked GCC documentation also lists other macros defined by the different GNU compilers.
In 6.10.8 Predefined macro names the C11 standard says (emphasis mine)
The implementation shall not predefine the macro __cplusplus, nor shall it define it in any standard header.
I believe C++ mandates a conforming implementation to define that name, so you can use it to differentiate languages
#ifdef __cplusplus
/* c++ code */
#else
/* c code */
#endif
I am creating a c++ dll to be imported in vb.net.
I have found that the best way to organize the imports and exports in the header file of the dll, is something of the following type:
#ifndef MY_DLL_EXPORTS
#define MY_DLL_EXPORT __declspec(dllexport)
#else
#define MY_DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
MY_DLL_EXPORT BOOL my_function(uint32_t x);
#ifdef __cplusplus
}
#endif
My question is, where are the __cplusplus and MY_DLL_EXPORTS supposed to be defined ?
I have not done this before and I can't seem to find a place in the code for it. I read something about putting these definitions in the
Project Properties -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions
Do I put them in the DLL's project properties ? and if i do, on using this DLL, will they always be defined so the if statement will always go to the dllimport ?
Also, is __cplusplus already defined or must I define it ?
__cplusplus is defined for you by a C++ compiler, but NOT by a C compiler. This is how you can determine if your code is being compiled by a C or C++ compiler. That's why this is used to guard the extern "C" construct. A C compiler would just omit it (since it emits C linkage already).
The other constants can be either defined on the compiler's command line (eg. in the menu you listed), or in the code somewhere:
#define MY_DLL_EXPORTS
Best place to define COMPILING_DLL 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.
Just a small question:
Can C++ use C header files in a program?
This might be a weird question, basically I need to use the source code from other program (made in C language) in a C++ one. Is there any difference between both header files in general? Maybe if I change some libraries...
I hope you can help me.
Yes, you can include C headers in C++ code. It's normal to add this:
#ifdef __cplusplus
extern "C"
{
#endif
// C header here
#ifdef __cplusplus
}
#endif
so that the C++ compiler knows that function declarations etc. should be treated as C and not C++.
If you are compiling the C code together, as part of your project, with your C++ code, you should just need to include the header files as per usual, and use the C++ compiler mode to compile the code - however, some C code won't compile "cleanly" with a C++ compiler (e.g. use of malloc will need casting).
If on, the other hand, you have a library or some other code that isn't part of your project, then you do need to make sure the headers are marked as extern "C", otherwise C++ naming convention for the compiled names of functions will apply, which won't match the naming convention used by the C compiler.
There are two options here, either you edit the header file itself, adding
#ifdef __cplusplus
extern "C" {
#endif
... original content of headerfile goes here.
#ifdef __cplusplus
}
#endif
Or, if you haven't got the possibility to edit those headers, you can use this form:
#ifdef __cplusplus
extern "C" {
#endif
#include <c_header.h>
#ifdef __cplusplus
}
#endif
Yes, but you need to tell the C++ compiler that the declarations from the header are C:
extern "C" {
#include "c-header.h"
}
Many C headers have these included already, wrapped in #if defined __cplusplus. That is arguably a bit weird (C++ syntax in a C header) but it's often done for convenience.
#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.