2011-07-27 2 views
12

У меня есть класс, который имеет две перегруженные функции. Как экспортировать его из DLL, а также как использовать его другими классами C++? Мой класс выглядит следующим образом:Как экспортировать класс C++ из 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"; 
} 
+0

К моему удивлению, я не сделал найти существующий вопрос, который этот дублирует. Я бы подумал, что это довольно распространенный вопрос. –

+0

Проверьте: http://stackoverflow.com/questions/6620791/exporting-classes-to-dlls – Ajay

ответ

18

Общий подход заключается в один макрос (назовем его 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

просто помните, что ответ Mehrdads правилен в том отношении, что экспортированные классы работают только для этой конкретной версии компилятора и параметров компилятора. Даже смешение Debug & Release не разрешено (например, отладочный клиент с использованием dll Release). –

1

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

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

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


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

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

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

файл заголовка (.h):

class MyClass { ... }; 

extern "C" DLL_API MyClass* createMyClass(); 

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

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

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

+2

Это самый простой способ его реализации. Но не забудьте поставить заводские функции во внешнем выражении «C» {}. Сбой имени C++ может помешать вам загрузить функцию из dll. – holgac

+0

Можете ли вы предложить мне пример –

3

Один другой вариант:

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

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

Свойства -> C/C++ -> препроцессора -> препроцессора определение.

Пример:

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

По умолчанию Macro Local к этому проекту: 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 { 
      //.... 
    } 
Смежные вопросы