GLEW - why should I define GLEW_STATIC? - opengl

I am using a statically linked library for GLEW and therefore I have to define GLEW_STATIC to compile my programs that are using GLEW. But I have never understood why this is necessary. So could anyone explain the reason?

When a function is implemented in a static library that must be specified. The extern keyword provides linkage information. A function which is imported from a dynamic library has to be marked by extern __declspec(dllimport). GLEW_STATIC is a preprocessor definition which activates the first case.
The relevant code part in the "glew.h" file (verison 2.1.0) is:
/*
* GLEW_STATIC is defined for static library.
* GLEW_BUILD is defined for building the DLL library.
*/
#ifdef GLEW_STATIC
define GLEWAPI extern
#else
ifdef GLEW_BUILD
define GLEWAPI extern __declspec(dllexport)
else
define GLEWAPI extern __declspec(dllimport)
endif
#endif

Related

Windows dynamic library conditional compilation, and C++/C mixing question

I am trying to understand some code that I have inherited, but am having some trouble googling my way out of it, and have some questions I hope some of you can help me with. The code can be seen just below, and is a .hpp (c++ header file) which declares a function.
#ifdef _MSC_VER
#define EXPORT_SYMBOL __declspec(dllexport)
#else
#define EXPORT_SYMBOL
#endif
#ifdef __cplusplus
extern "C" {
#endif
EXPORT_SYMBOL float func(int int_param, float float_param);
#ifdef __cplusplus
}
#endif
My first point of confusion is
#ifdef _MSC_VER
#define EXPORT_SYMBOL __declspec(dllexport)
#else
#define EXPORT_SYMBOL
#endif
I understand this as "if we are compiling from a windows machine, do something special".
What does __declspec(dllexport) do exactly?
Why do I need EXPORT_SYMBOL at all?
Secondly I am confused about the necessity of wrapping the header in the extern "C" statement. As far as I can tell the header is checking to see if __cplusplus is defined, that is, if we are compiling with g++. The extern block is here to make sure I don't have issues with the g++ compiler if func() was found in say, a file called func.c instead of a .cpp file, and then compiled with gcc. I understand mangling, and how g++ changes function names to enable overloading.
As i have it contained in a .cpp file and hence intend to exclusively compile it with g++, do I need the extern "C" block, and #ifdef statements? Is there a case where this is crucial?
What does __declspec(dllexport) do exactly?
When DLL is created, it does not export any symbols by default (unlike static library). In Visual C++, __declspec(dllexport) is the easiest way to export symbols. There are other ways to export.
As i have it contained in a .cpp file and hence intend to exclusively
compile it with g++, do I need the extern "C" block, and #ifdef
statements? Is there a case where this is crucial?
This allows using the function if you load the DLL from a C program, from a C++ program built by any compiler, or even from other languages with C bindings. If you work exclusively with C++ and g++ compiler, there is still a case when this is important: loading the DLL dynamically - in which case you need to supply your function name as a string (mangled unless you use extern "C").

What are the different ways with which we can dynamically Link a DLL

I want to link a .dll dynamically.
What are the multiple ways to do so?
One way I know, is by using HMODULE WINAPI LoadLibrary(_In_ LPCTSTR lpFileName)
function.
Is there any other way?
I am trying to understand the below code:
#if defined WIN32
// We want to define DTE_DLL_EXPORT if we are making
// a dll, but not if we are making a static library...
#if defined DTE_STATIC
#define GFITDTE_ENTRYPT
#else
#if defined _GFITDTE_BUILD_
#define GFITDTE_ENTRYPT __declspec(dllexport)
#else
#if defined DTE_IMPORT
#define GFITDTE_ENTRYPT __declspec(dllimport)
#else
#define GFITDTE_ENTRYPT
#endif
#endif
#endif
#else // Not WIN32
Can some on explain the above code??
The code shown has nothing to do with LoadLibrary. It's typical for header files, which in turn means you're building a DLL that's NOT supposed to be loaded via LoadLibrary. Instead, the compiler knows the function prototypes from the header, and the linker uses an import library to set up the DLL linking.

What does #ifdef WIN32DLL_EXPORTS mean?

I've created a DLL a file, and in the header file I see :
#ifdef WIN32DLL_EXPORTS
I don't understand what does it mean and where/how we can set up WIN32DLL_EXPORTS.
if I use:
#ifdef WIN32DLL_EXPORTS
#define WIN32DLL_API __declspec(dllexport)
#else
#define WIN32DLL_API __declspec(dllimport)
#endif
WIN32DLL_API int testSum(void);
testSum is considered as __declspec(dllimport). So I think my project is not set to WIN32DLL_EXPORTS? How can I change this?
There is a comment block immediately above the line you quoted. Read it.
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the WIN32DLL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// WIN32DLL_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#ifdef WIN32DLL_EXPORTS
#define WIN32DLL_API __declspec(dllexport)
#else
#define WIN32DLL_API __declspec(dllimport)
#endif
You can either:
define WIN32DLL_EXPORTS in the project's Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor definitions.
if you use a precompiled header (e.g. stdafx.h) then you can also define WIN32DLL_EXPORTS
there with a #define statement.

Creating a portable library to run on both linux and windows

gcc (GCC) 4.7.2
Hello,
I am creating a shared library that will compile on linux and a dll that will compile on windows using the same source code. So i am creating an portable library for both linux and windows.
In my header file for the library is this i.e. module.h
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
#define LIB_INTERFACE(type) EXTERN_C __declspec(dllexport) type
#else
#define LIB_INTERFACE(type) type
#endif
LIB_INTERFACE(int) module_init();
#ifdef __cplusplus
}
#endif
In the source I have the following i.e. module.c
#include "module.h"
LIB_INTERFACE(int) module_init()
{
/* do something useful
return 0;
}
And in my test application that will link and use this module.so I have this:
#include "module.h"
int main(void)
{
if(module_init() != 0) {
return -1;
}
return 0;
}
1) Is what I have done above is it a correct implementation of creating a portable library for linux and windows?
2) I am just wondering as I have wrapped the functions in extern "C" so that this library can been called from a program that has been compiled in C++. Do I still need this EXTERN_C in the following:
#define LIB_INTERFACE(type) EXTERN_C __declspec(dllexport) type
3) What is the purpose of the EXTERN_C?
Many thanks in advance,
This is a typical way to export a DLL API for Windows and still support Linux:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
# ifdef MODULE_API_EXPORTS
# define MODULE_API __declspec(dllexport)
# else
# define MODULE_API __declspec(dllimport)
# endif
#else
# define MODULE_API
#endif
MODULE_API int module_init();
#ifdef __cplusplus
}
#endif
In the DLL source:
#define MODULE_API_EXPORTS
#include "module.h"
MODULE_API int module_init()
{
/* do something useful */
return 0;
}
Your application source is correct.
Using the above model, on Windows the DLL will export the API while the application will import it. If not on Win32, the __declspec decoration is removed.
Since the header wraps the entire interface in extern "C", using the EXTERN_C macro on each interface is not required. extern "C" is used to tell the linker to use C linkage instead of C++. C linkage is standard across compilers, whereas C++ is not, limiting the use of a DLL to application built with the same compiler.
There is no need to integrate the return type into the API macro.
extern "C" basically means that you are telling the compiler not to mangle your function name.
Mangling is the process of "encoding" function names for later execution and is quite different in C and C++ as C++ can have different functions having the same name (via overloading etc...).
In C++ source, what is the effect of extern "C"?
Once compiled these functions can be called from anywhere but you might want to be sure what kind of library you are creating (static or dynamic) before you start.
Also I recommend you not using DEFINES like you do in the same file for portability purposes because of the maintenance or readability problems you might encounter later in the development.
I would create a basic file defining an interface which is fully portable to WIN and UNIX then create two other libraries implementing the interface but for different platforms.
For example you can have:
AbstractInterface.h, WinInterface.h, UnixInterface.h
Then only compile the ones you need depending on the platform.
For Linux, gcc without -fvisibility=hidden will make functions exported by default, except for static functions.
With -fvisibility=hidden, gcc will make no functions exported by default, except that functions decorated by
__attribute__ ((visibility ("default")))
For Windows, exported functions decorated by
__attribute__ ((dllexport))
when using the exported functions, they must be decorated by
__attribute__ ((dllimport))
The macros in your posts
__declspec(dllexport)
are supported by MSVC.
So the crossed linux and windows macros are as following:
#if defined _WIN32 || defined __CYGWIN__ || defined __MINGW32__
#ifdef BUILDING_DLL
#ifdef __GNUC__
#define DLL_PUBLIC __attribute__ ((dllexport))
#else
#define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
#endif
#else
#ifdef __GNUC__
#define DLL_PUBLIC __attribute__ ((dllimport))
#else
#define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
#endif
#endif
#define DLL_LOCAL
#else
#if __GNUC__ >= 4
#define DLL_PUBLIC __attribute__ ((visibility ("default")))
#define DLL_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define DLL_PUBLIC
#define DLL_LOCAL
#endif
#endif
Make sure that shared object or DLL projects must be compiled
with -DBUILDING_DLL.
The project that depends on your shared object or DLL must be compiled without -DBUILDING_DLL
For the more details, please read http://gcc.gnu.org/wiki/Visibility
Due to the concept of polymorphism which is specific to c++ language, All the functions defined in c++ are mangled. i.e., to create unique names for each overridden function, the "compiler" decorates the function names.
Since name mangling is handled by "compiler" and there is no specification to strictly define the name mangling rules, each compiler decorates the names in different ways. Simply put, gcc and msvc compilers create different function signatures for the same code. you can read further about name mangling at the wiki article here.
Your module.h file simply tells the compiler to use c style name mangling or no mangling at all. due to this directive, the library that is compiled by gcc can be used to link to a binary that is written in visual studio. This will help you to distribute the binaries of your library instead of source code.
On the other hand, if you do not use the EXTERN_C directive, the library and the project that links to the library should be compiled using same compiler. for example, you have to use gcc for linux compilation and msvc for windows compilation for both the library and the project linking to that library.
Instead of writing a header file yourself, you can also let CMake generate one for the building compiler using CMake's generate_export_header like this (examples taken from the linked page):
add_library(libfoo foo.cpp)
generate_export_header(libfoo)
#include "libfoo_export.h"
class LIBFOO_EXPORT FooClass {
int bar;
};

Q_DECL_EXPORT keyword meaning

Q_DECL_EXPORT int main(int argc, char **argv)
What does this Q_DECL_EXPORT before int main(...) means?
Excerpt from QT docs:
Depending on your target platform, Qt provides special macros that
contain the necessary definitions:
Q_DECL_EXPORT must be added to the declarations of symbols used when compiling a shared library.
Q_DECL_IMPORT must be added to the declarations of symbols used when compiling a client that uses the shared library.
I haven't check the QT code, but most likely this macro will do following:
#ifdef _WIN32 || _WIN64
#define Q_DECL_EXPORT __declspec(dllexport)
#define Q_DECL_IMPORT __declspec(dllimport)
#else
#define Q_DECL_EXPORT
#define Q_DECL_IMPORT
#endif
__declspec(dllimport) and __declspec(dllexport) tells the linker to import and export (respectively) a symbol from or to a DLL. This is Windows specific.
In your particular case this macro probably could be removed, since main() most likely is not part of a library.
Its not a keyword, its a macro to encapsulate the different compiler specific keywords to declare a function as being exported.
See also Q_DECL_EXPORT and Creating Shared Libraries.
It is usually used with libraries to define those functions which need to be exported from the library, in order to be imported ("used") by other libraries or by executables.
I have not seen this with a main function so far, but that could be a blackberry specific thing. On the other hand, this tutorial does not use the macro with the main() function either, so it can probably be removed.