2011-07-27 20 views
12

Mam klasę, która ma dwie przeciążone funkcje. Jak wyeksportować go z biblioteki dll, a także jak go używać w innych klasach C++? Moja klasa wygląda następująco:Jak wyeksportować klasę C++ z biblioteki 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

Ku mojemu zaskoczeniu, ja nie znajdź istniejące pytanie, które się powiela. Pomyślałem, że to dość powszechne pytanie. –

+0

Sprawdź: http://stackoverflow.com/questions/6620791/exporting-classes-to-dlls – Ajay

Odpowiedz

18

Typowym rozwiązaniem jest mieć pojedynczy makro (nazwijmy go EXPORT), które albo rozszerza się dllimport lub dllexport w zależności od tego, czy jakiś „budowania DLL teraz” określają to ustawiony tak:

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

class EXPORT xyz { 
    // ... 
}; 

Chodzi o to, że podczas tworzenia biblioteki DLL, należy dodać MAKEDLL do definicji preprocesora. W ten sposób cały kod zostanie wyeksportowany. Klienci, którzy łączą się z twoją biblioteką DLL (i tym samym dołączają ten plik nagłówkowy), nie muszą w ogóle nic robić. Nie definiując MAKEDLL, automatycznie zaimportują cały kod.

Zaletą tego podejścia jest to, że obciążenie związane z uzyskaniem właściwych makr jest przenoszone z wielu (klientów) do samego autora biblioteki DLL.

Wadą tego jest to, że używając powyższego kodu, nie można już po prostu skompilować kodu bezpośrednio do jakiegoś modułu klienta, ponieważ nie można zdefiniować makra EXPORT na nic. Aby to osiągnąć, musisz mieć kolejną kontrolę, która jeśli jest prawdziwa, definiuje EXPORT na nic.

Na nieco inny temat: w wielu przypadkach nie jest możliwe (lub pożądane!) Wyeksportowanie całej takiej klasy. Zamiast tego możesz po prostu wyeksportować potrzebne symbole. Na przykład w twoim przypadku możesz po prostu wyeksportować dwie publiczne metody. W ten sposób wszyscy członkowie prywatne/zabezpieczone nie zostaną wyeksportowane:

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

Pamiętaj tylko, że odpowiedź Mehrdads jest poprawna pod tym względem, że wyeksportowane klasy działają tylko dla tej konkretnej wersji kompilatora i kompilatora. Nawet mieszanie Debug & Release jest niedozwolone (np. Debugowanie klienta za pomocą Release dll). –

1

Podczas kompilowania biblioteki należy zdefiniować makro (linia poleceń definicji preprocesora), nazwijmy to MY_DLL_EXPORT.

Następnie w kodzie biblioteki zrobić coś takiego:

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


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

Jak pamiętam, normalnie, nie eksportować klasy, lecz funkcję fabryki, który tworzy nową instancję klasy i zwraca wskaźnik. Deklaracja klasy znajduje się w pliku nagłówkowym dla czasu kompilacji.

mogę się mylić o przykład (to było dawno temu), ale tutaj jak to powinno wyglądać w przybliżeniu:

pliku nagłówka (.h):

class MyClass { ... }; 

extern "C" DLL_API MyClass* createMyClass(); 

plik źródłowy (.cpp):

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

Definiujemy MY_DLL_EXPORT podczas kompilacji, zobacz przykład odpowiedzi foraidt.

+2

To najprostszy sposób na jego wdrożenie. Ale nie zapomnij umieścić funkcji fabrycznych w zewnętrznej instrukcji "C" {}. Wymazywanie nazw C++ może uniemożliwić ładowanie funkcji z biblioteki dll. – holgac

+0

możesz mi zaproponować przykład –

3

Jedna inna opcja:

Użyj domyślne zdefiniowane makro lokalny do projektu.

Widać domyślne zdefiniowane makra lokalnych do projektu w poniższej lokalizacji:

Właściwości -> C/C++ -> Preprocessor -> preprocesora definicję.

Przykład:

Załóżmy, że nazwa projektu brzmi: MyDLL

domyślne Macro lokalne do tego projektu: 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 { 
      //.... 
    } 
Powiązane problemy