Explicitly exporting shared library functions in Linux - c++

Is there a Linux equivalent of __declspec(dllexport) notation for explicitly exporting a function from a shared library? For some reason with the toolchain I'm using, functions that aren't class members don't appear in the resulting shared library file.

__attribute__((visibility("default")))
And there is no equivalent of __declspec(dllimport) to my knowledge.
#if defined(_MSC_VER)
// Microsoft
#define EXPORT __declspec(dllexport)
#define IMPORT __declspec(dllimport)
#elif defined(__GNUC__)
// GCC
#define EXPORT __attribute__((visibility("default")))
#define IMPORT
#else
// do nothing and hope for the best?
#define EXPORT
#define IMPORT
#pragma warning Unknown dynamic link import/export semantics.
#endif
Typical usage is to define a symbol like MY_LIB_PUBLIC conditionally define it as either EXPORT or IMPORT, based on if the library is currently being compiled or not:
#if MY_LIB_COMPILING
# define MY_LIB_PUBLIC EXPORT
#else
# define MY_LIB_PUBLIC IMPORT
#endif
To use this, you mark your functions and classes like this:
MY_LIB_PUBLIC void foo();
class MY_LIB_PUBLIC some_type
{
// ...
};

Related

How to declare a class shared between a library and an application

I have a common utility class that is shared between two projects, an desktop application project and a library project (dll). I'm working under VS2013.
To make this class available to external calls when it's compiled as part of my library, I use a macro like this:
#include "global.h"
class MYCLASS_EXPORT UtilityClass {
public:
...
My global.h file contains the following:
#ifdef MYCLASS_LIBRARY
# define MYCLASS_EXPORT __declspec(dllexport)
#else
# define MYCLASS_EXPORT __declspec(dllimport)
#endif
So when I use that class inside my library I set the preprocessor macro MYCLASS_LIBRARY and an application that link my library can use the UtilityClass.
Instead, when I use that class as part of my C++ desktop application project (that doesn't have the preprocessor macro MYCLASS_LIBRARY), I get from the compiler an "inconsistent dll linkage" error because of MYCLASS_EXPORT declaration.
So, how to declare my class so that can be used both in a library project and in a desktop application project (so without the need to export that class)?
Just to be more clear, a working solution I've found is the following:
#ifdef MYCLASS_LIBRARY
#include "global.h"
#endif
#ifdef MYCLASS_LIBRARY
class MYCLASS_EXPORT UtilityClass {
#else
class UtilityClass {
#endif
public:
...
Now everything compile and run fine, but does not seem a good approach...
I can think of the following option:
In the desktop application, define a macro, MYCLASS_STATIC and change the .h file to use:
#ifdef MYCLASS_STATIC
# define MYCLASS_EXPORT
#elif defined(MYCLASS_LIBRARY)
# define MYCLASS_EXPORT __declspec(dllexport)
#else
# define MYCLASS_EXPORT __declspec(dllimport)
#endif

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.

what does __declspec(dllexport) do , when add it before a import function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Windows & C++: extern & __declspec(dllimport)
Why/when is __declspec( dllimport ) not needed?
I want to write a DLL project. This project include several DLLs. They are dependent. I define some macros like follow :
#ifdef MYDLL_DECL1
#define DLL_DECL __declspec(dllexport)
#else
#define DLL_DECL __declspec(dllimport)
#endif
I defined MYDLL_DECL1...MYDLL_DECLn for each modules. Because I thought if i define the same macro that it wouldn't work . But I really want to define only one macro, and i wrote a testbed. I have two modules. In the second moudle's source file. I write code like follow:
#define MYDLL_DECL
#include "moudle1.h"
#include "moudle2.h"
If I use the same macro name "MYDLL_DECL" ,for modle1's head file I have defined "MYDLL_DECL", so "DLL_DECL" is equal to '__declspec(dllexport)'. Actually in module2 it should be equal to "__declspec(dllimport)", Because module2 import module1. But I found it worked when I just define a same macro for two module. And I also find that the OpenCV also use this methold to its library
First, think about what you need without the macro. If a class or
function is defined in module1, you need to declare it
__declspec(dllexport) in module1, and __declspec(dllimport) in all
of the other modules. Including in the header file where it is
declared.
Since you don't want to maintain two different header files, and you
don't what conditional compilation all over the place, the best solution
is use a conditionally defined macro, e.g.:
#ifdef MODULE1
#define MODULE1_DECL __declspec(dllexport)
#else
#define MODULE1_DECL __declspec(dllimport)
#endif
When invoking the compiler, you only define MODULE1 in the project
module1; you don't define it in any other project. So when compiling
module1, MODULE1_DECL expands to __declspec(dllexport), and when
compiling any other module, it expands to __declspec(dllimport).

Meaning of "CC_DLL" in this line"class CC_DLL CCSize" in Cocos2d-x

What is the specification of CC_DLL in this line"class CC_DLL CCSize" in Cocos2d-x.
Every Class in cocos2d-x Define like that --> class ..... classname
It create confusion for me. Plz help me out.
Thanks,
It's probably a preprocessor definition telling the module to either export or import the class.
Something like:
#ifdef BUILDING_COCOS
#define CC_DLL _declspec(dllexport)
#else
#define CC_DLL _declspec(dllimport)
#endif
When linking against the library, BUILDING_COCOS is not defined, so CC_DLL will mean _declspec(dllimport), which tells the compiler that the class is exported in a binary.
I assume CC_DLL to be defined something like this (using MSVC intrinsics syntax):
#ifdef CC_IS_IMPLEMENTATION /* or CC_IS_DLL_COMPILATION or something like that */
#define CC_DLL __declspec(dllexport)
#else
#define CC_DLL __declspec(dllimport)
#endif
This is done to have a single definition that either exports or imports the class to/from a dll, based on whether the API is used by a user or by the implementation itself. The implementation (.cpp file) would then look something like this:
// .cpp file
#define CC_IS_IMPLEMENTATION
// CC_DLL is now defined to __declspec(dllexport)
#include "myapi_stuff.h"
// implement it...
And if a library / dll user uses that API (class), it is defined as __declspec(dllimport) to import the implementation from a dll.

Alternatives for empty macros

In my C++ header file, I have the following:
#ifdef _DLL
#define DLL_API __declspec(dllexport) // Being compiled as a DLL.
#else
#define DLL_API // Not being compiled as a DLL.
#endif
Later on, I have things like:
DLL_API int GetNumber();
I'm oversimplifying, but the basic question here is whether there's a way to get the compiler to just skip over DLL_API if it's not defined.
No.
When DLL_API is defined as preprocessor macro that contains nothing then preprocessor replaces DLL_API with nothing and compiler will see nothing there. If it is undefined for preprocessor then preprocessor does nothing with it. Then compiler will see it unchanged and you get compiler error about unknown identifier DLL_API, because such thing is not part of C++ language.
Attributes like __declspec() are platform specific extensions and it is common convention to wrap their usage in interfaces into preprocessor macros.
Usually, it is
#ifdef _WIN32
#ifdef _DLL
#define DLL_API __declspec(dllexport) // Being compiled as a DLL.
#else
#define DLL_API __declspec(dllimport) // Not being compiled as a DLL.
#endif
#else
#define DLL_API
#endif
so that it is portable, and DLL_API is always transformed into something valid.