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.