Подтвердить что ты не робот

Как экспортировать класс С++ из DLL?

У меня есть класс, который имеет две перегруженные функции. Как экспортировать его из DLL, а также как использовать его другими классами С++? Мой класс выглядит следующим образом:

#define DECLDIREXP __declspec(dllexport) 

#define DECLDIRIMP __declspec(dllimport)


class DECLDIREXP xyz 

{

public: 
          void printing();
          void printing(int a);
};  

using namespace std; 

void xyz::printing()
{
        cout<<"hello i donot take any argument";
}


void xyz::printing(int a)
{
        cout<<"hello i take "<< a <<"as argument";
}
4b9b3361

Ответ 1

Общим подходом является наличие одного макроса (пусть он вызывает его EXPORT), который либо расширяется до dllimport, либо dllexport в зависимости от того, установлено ли какое-то определение "создание DLL прямо сейчас",

#ifdef MAKEDLL
#  define EXPORT __declspec(dllexport)
#else
#  define EXPORT __declspec(dllimport)
#endif

class EXPORT xyz {
  // ...
};

Идея заключается в том, что при создании вашей DLL вы добавляете MAKEDLL в определения препроцессора. Таким образом, весь код будет экспортироваться. Клиенты, которые ссылаются на вашу DLL (и, следовательно, включают этот заголовочный файл), вообще ничего не должны делать. Не определяя MAKEDLL, они автоматически импортируют весь код.

Преимущество такого подхода заключается в том, что бремя получения макросов вправо перемещается от многих (клиентов) только к автору DLL.

Недостатком этого является то, что при использовании вышеприведенного кода уже невозможно просто скомпилировать код непосредственно в некоторый клиентский модуль, так как невозможно определить макрос EXPORT до нуля. Для этого вам нужно будет иметь еще одну проверку, которая, если она истинна, ничего не определяет EXPORT.

В несколько другой теме: во многих случаях невозможно (или желательно!) экспортировать полный класс. Вместо этого вы можете просто экспортировать нужные символы. Например, в вашем случае вы можете просто экспортировать два общедоступных метода. Таким образом, все частные/защищенные члены не будут экспортироваться:

class xyz
{
public: 
    EXPORT void printing();
    EXPORT void printing(int a);
};

Ответ 2

Как я помню, обычно вы экспортируете не класс, а функцию factory, которая создает новый экземпляр класса и возвращает указатель. Объявление класса находится в заголовочном файле для времени компиляции.

Возможно, я ошибаюсь в примере (это было давно), но вот как это должно выглядеть примерно так:

Заголовочный файл (.h):

class MyClass { ... };

extern "C" DLL_API MyClass* createMyClass();

Исходный файл (.cpp):

DLL_API MyClass* createMyClass() {
    return new MyClass();
}

Определите MY_DLL_EXPORT во время компиляции, см. пример ответа.

Ответ 3

Один из вариантов:

Используйте по умолчанию определенный макрос локальный для проекта.

Макросы, определенные по умолчанию, локальны для проекта в нижерасположенном месте:

Свойства → C/С++ → Препроцессор → Определение препроцессора.

Пример:

Предположим, что ваше имя проекта: MyDLL

Макрос по умолчанию для этого проекта: 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


  class DLLEXPORT  Class_Name { 
             //.... 
  }

Ответ 4

При компиляции вашей библиотеки вы должны определить макрос (определение препроцессора командной строки), позвоните ему MY_DLL_EXPORT.

Затем в вашем коде библиотеки сделайте что-то вроде этого:

#ifdef MY_DLL_EXPORT
#  define DLL_API __declspec(dllexport)
#else
#  define DLL_API __declspec(dllimport)
#endif


class DLL_API some_class { /*...*/ }