c++ windows visual-studio dll vtable

Cómo usar la carga de retraso con una DLL que exporta clases de C++



windows visual-studio (4)

Tengo un archivo DLL one.dll que usa una clase TwoClass exportada desde two.dll través de la class __declspec(dllexport) . Me gustaría que one.dll use /delayload para two.dll , pero me da un error de enlace:

LINK : fatal error LNK1194: cannot delay-load ''two.dll'' due to import of data symbol ''"__declspec(dllimport) const TwoClass::`vftable''" (__imp_??_7TwoClass@@6B@)''; link without /DELAYLOAD:two.dll

Eso está en una versión de Release; en una compilación de depuración funciona. (No sé cuál es la diferencia entre Release y Debug en términos de exportaciones vtable, ni puedo encontrar ningún compilador de switches o pragmas para controlarlo).

¿Cómo puedo usar /delayload con una DLL que exporta clases como esta en una versión de lanzamiento?


Defina una función de fábrica que distribuya instancias de una clase, como en COM. Esto también requiere que las interfaces de las clases sean públicas, pero eso también se da cuando alguien importa una clase.


Compruebe si one.dll contiene un archivo fuente que incluye TwoClass.hxx pero no lo usa realmente. Además, verifique si TwoClass cumple con las condiciones para los métodos generados por el compilador (consulte las condiciones para la generación automática ).

En mi caso, en realidad no necesitaba una copiadora generada por el compilador ni el operador de asignación para TwoClass, así que los declare en la sección private: sin proporcionar una definición. Eso creó errores de compilación para one.dll, que me guiaron a los archivos fuente que innecesariamente incluían TwoClass.hxx. Después de eliminar lo innecesario, pude compilar y vincular con la optimización activada y con / delayload.

Supongo que las declaraciones #include innecesarias equivocaron al optimizador para copiar los métodos generados por el compilador para TwoClass en los archivos .obj para vincularlos en one.dll, aunque no se usaron en estos archivos .obj. Estos métodos innecesarios generados por el compilador para TwoClass parecen evitar un enlace con / delayload.


Echa un vistazo aquí , parece que la persona tenía exactamente el mismo problema y encontró una solución alternativa

Pude hacer que la carga de la demora funcionara en la versión de lanzamiento al deshabilitar las optimizaciones en la unidad de traducción que usaba la clase SomeClass; de alguna manera se eliminó la dependencia de la tabla exportada.


Tuve exactamente el mismo problema con la clase que contenía la implementación en línea para la clase exportada.

class __declspec(dllimport) VidExpInternal : public VidExpBase { public: VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__)) : VidExpBase (msg,ln,filechar) {}

Trasladé la implementación en línea al archivo .cpp, después de eso todo salió bien.

class __declspec(dllimport) VidExpInternal : public VidExpBase { public: VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__));