2012-03-17 11 views
12

Quiero definir una clase derivada basada en una clase dll exportada. La clase base se define en el Proyecto A, y la clase derivada se encuentra en el Proyecto B.símbolo externo no resuelto para __declspec (dllimport) cuando se utiliza dll para exportar la clase

En primer lugar, en el Proyecto A, se define el preprocesador MYDLL_BUILD. Y utilizo un archivo de cabecera para especificar la exportación/importación:

#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 

Entonces definir la clase base:

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

En Proyecto B, el preprocesador MYDLL_BUILD no está definido. Esta es la clase derivada:

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

He incluido el DLL y el archivo lib, pero todavía tengo la no resuelta símbolo de error externa:

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 

me realizaron búsquedas en línea, la mayoría de las respuestas afirman que la lib no se encuentra. Pero esas instrucciones no resuelven mi problema.

Cuando cambio

class MYDLL_API DllObject 

a

class __declspec(dllexport) DllObject 

La solución compila sin error. Realmente no entiendo la razón. ¿Puede ayudarme alguien, por favor? Gracias por adelantado.

+1

Parece que 'MYDLL_API' no está definido en el Proyecto A como espera. Obtenga VS para generar una versión preprocesada del archivo en el que está definido DllObject (haga clic con el botón derecho en el archivo, vaya a propiedades, expanda C/C++ y busque las opciones del preprocesador). Asegúrese de que la salida contenga 'clase __declspec (dllexport) DllObject' y no' clase __declspec (dllimport) DllObject' – Praetorian

+0

Esos errores de enlazador no se pueden generar para el fragmento de código que ha publicado. Usted escribió el código en el archivo de encabezado. Entonces, cuando #includes, no hay ninguna dependencia en el .lib de la DLL. En caso de que no estemos viendo el código real, simplemente parece que de alguna manera no # definió MYDLL_BUILD correctamente. –

+0

Gracias por responder. DllObject solo tiene un archivo de cabecera, no hay ningún archivo cpp. No puedo generar un archivo preprocesado para DllObject. El preprocesador MYDLL_BUILD se define en las propiedades del Proyecto A. Los códigos que pegué arriba son códigos reales, pero es solo la parte que creo que está relacionada con el mensaje de error. – Chtoucas

Respuesta

6

El motivo está en la línea interior.

En resumen, para que las funciones en línea sean posibles, C++ debe permitir que la misma definición de función se incluya y compile en varias unidades de compilación (básicamente archivos .cpp) sin causar errores. El compilador puede, pero no tiene que emitir código para ninguna de estas definiciones. Entonces el enlazador puede elegir una copia.

Esto complica la creación dll porque necesita exportar exactamente una copia pero el compilador no sabe qué copia es la correcta. En este caso, al agregar un código a DllObject.cpp, el compilador emitió el código para DllObject y el vinculador tuvo una copia de DllObject::~DllObject para exportar.

No puedo darle una explicación más detallada de su caso particular porque no conozco las opciones completas de fuente y compilación para su proyecto.

+3

Incluyendo el .h en un módulo .cpp no fue suficiente para crearlo? Se podría pensar que la generación de DLL podría al menos señalar esto como un error ... –

Cuestiones relacionadas