2012-03-17 12 views
12

Chcę zdefiniować klasę pochodną w oparciu o wyeksportowaną klasę dll. Klasa podstawowa jest zdefiniowana w Projekcie A, a klasa pochodna jest w Projekcie B.nierozwiązany symbol zewnętrzny dla __declspec (dllimport) podczas używania biblioteki dll do eksportu klasy

Po pierwsze, w Projekcie A zdefiniowano preprocesor MYDLL_BUILD. I użyć pliku nagłówka określić eksport/import:

#if !defined(MYDLL_BUILD) 
    # pragma comment(lib, "myDll.lib") 
    #endif 

    #if defined(MYDLL_BUILD) 
    # define MYDLL_API __declspec(dllexport) 
    #else 
    # define MYDLL_API __declspec(dllimport) 
    #endif 

Potem zdefiniować klasę bazową:

class MYDLL_API DllObject 
{ 
public: 
    virtual ~DllObject() {} 
protected: 
    DllObject() { m_count = 3; } 
private: 
    int m_count; 
}; 

W projekcie B, MYDLL_BUILD preprocesor nie jest zdefiniowana. Oto klasa pochodna:

class MyClass : public DllObject 
{ 
public: 
    ~MyClass(){} 
    MyClass() { m_data = 20; } 
private: 
    int m_data; 
}; 

mam włączone dll i lib plik, ale nadal mam nierozwiązanych zewnętrznego błędu Symbol:

2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ADAI::DllObject::~DllObject(void)" ([email protected]@@[email protected]) referenced in function "public: virtual __thiscall MyClass::~MyClass(void)" ([email protected]@[email protected]) 
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __thiscall ADAI::DllObject::DllObject(void)" ([email protected]@@[email protected]) referenced in function "public: __thiscall MyClass::MyClass(void)" ([email protected]@[email protected]) 
2>c:\Users\Adai\Documents\Visual Studio 2010\Projects\Test_Main\Debug\Test_Main.exe : fatal error LNK1120: 2 unresolved externals 

I wyszukiwane w Internecie, większość odpowiedzi twierdzą, że brak biblioteki. Ale te instrukcje nie rozwiązują mojego problemu.

Kiedy zmienić

class MYDLL_API DllObject 

do

class __declspec(dllexport) DllObject 

Rozwiązanie kompiluje bez błędów. Naprawdę nie rozumiem powodu. Czy ktoś może Ci pomóc? Z góry dziękuję.

+1

Wydaje się, że 'MYDLL_API' nie jest zdefiniowany w Projekcie A tak, jak tego oczekujesz. Pobierz VS, aby wygenerować wstępnie przetworzoną wersję pliku, który definiuje DllObject (kliknij prawym przyciskiem myszy na pliku, przejdź do właściwości, rozwiń C/C++ i sprawdź opcje preprocesora). Upewnij się, że dane wyjściowe zawierają 'class __declspec (dllexport) DllObject', a nie' class __declspec (dllimport) DllObject' – Praetorian

+0

Nie można wygenerować błędów łącznika w opublikowanym fragmencie kodu. Napisałeś kod w pliku nagłówkowym. Tak więc, gdy #include to, nie ma żadnego uzależnienia od biblioteki DLL .lib. Na wypadek, gdybyśmy nie patrzyli na prawdziwy kod, brzmi to tak, jakbyście nie poprawili poprawnie #Define MYDLL_BUILD. –

+0

Dzięki za odpowiedź. DllObject ma tylko plik nagłówkowy, nie ma pliku cpp. Nie mogę wygenerować wstępnie przetworzonego pliku dla obiektu DllObject. Preprocesor MYDLL_BUILD jest zdefiniowany we właściwościach Projektu A. Kody, które wkleiłem powyżej, są kodami rzeczywistymi, ale to tylko część, którą myślę, powiązaną z komunikatem o błędzie. – Chtoucas

Odpowiedz

6

Powód jest inline.

W skrócie, aby możliwe funkcje inline C++ musi umożliwiać włączenie tej samej definicji funkcji i kompilację w wielu jednostkach kompilacji (w zasadzie plikach .cpp) bez powodowania błędów. Kompilator może, ale nie musi emitować kodu dla żadnej z tych definicji. Następnie linker może wybrać jedną kopię.

To komplikuje tworzenie biblioteki DLL, ponieważ trzeba wyeksportować dokładnie jedną kopię, ale kompilator nie wie, która kopia jest właściwa. W tym przypadku, dodając jakiś kod do DllObject.cpp, kompilator wyemitował kod dla DllObject, a linker miał do eksportu pewną kopię DllObject::~DllObject.

Nie mogę podać bardziej szczegółowego wyjaśnienia konkretnego przypadku, ponieważ nie znam opcji pełnego źródła i opcji kompilacji dla Twojego projektu.

+3

Więc włączając .h w module .cpp nie było wystarczające, aby go stworzyć? Można by pomyśleć, że generacja DLL może przynajmniej oznaczać to jako błąd ... –

Powiązane problemy