2009-10-04 18 views

Respuesta

3

Respondiendo a su pregunta en sentido estricto, es necesario agregar una función extern "C" que devuelve el resultado del constructor:

extern "C" foo* __declspec(dllexport) new_foo(int x) { 
    return new foo(x); 
} 

Luego, en su fuente se puede utilizar GetProcAddr en "new_foo" para llamar a la función .

3

Deberá exportar una función de la DLL que llama al constructor y devuelve el nuevo objeto.

Trate de evitar el uso de tipos concretos de C++ como parámetros de función; La idea de las DLL es que usted puede actualizarlas independientemente, pero un compilador actualizado puede diseñar std :: string de manera diferente, causando incompatibilidad en el tiempo de ejecución.

Esto es lo que está en la raíz de COM, por ejemplo, un sistema de tipo limitado y una función exportada estándar para obtener instancias de objetos.

+0

Parece que la fuente de la DLL no está bajo su control. –

+0

fuente DLL está bajo mi control – SomeUser

+0

Si la clase está destinada a ser utilizada, entonces probablemente ya debe ser compilada con __declspec (dllexport), entonces solo es cuestión de convencer al archivo de encabezado para poner __declspec (dllimport) en el definición de clase. De lo contrario, siempre puede modificar el archivo de encabezado usted mismo. – JesperE

10

Debe declarar su clase utilizando la palabra clave __declspec(dllexport) al compilar la DLL. Cuando se utiliza el archivo DLL, la clase debe ser declarada con __declspec(dllimport):

#ifdef COMPILING_DLL 
#define DECLSPEC_CLASS __declspec(dllexport) 
#else 
#define DECLSPEC_CLASS __declspec(dllimport) 
#endif 

class DECLSPEC_CLASS MyClass 
{ 
... 
} 

Cuando se compila el DLL, se debe añadir -DCOMPILING_DLL a la lista de los define.

Al utilizar la clase, debe vincular estáticamente con la DLL, es decir, pasar la biblioteca de importación mydll.lib al programa principal.

Si desea cargar la DLL en tiempo de ejecución, necesita tener una función C en la DLL que crea un objeto y lo devuelve. No hay forma de buscar un constructor dinámicamente en una DLL (usando GetProcAddress()).

+1

¿Puedes citar una fuente para la última declaración? AFAIK un ctor tiene un nombre destrozado, y usted puede llamar a GetProcAddress usando ese nombre. ¿Qué te detendría? – MSalters

+0

Sí, técnicamente tienes razón. – JesperE

3

En lugar de exportar todos los métodos de la clase utilizando declspec, también se puede confiar en el hecho de que el compilador puede invocar funciones virtuales a través de la viable, así por ejemplo:

//note: no __declspec 
class IPublicInterface 
{ 
    virtual ~IPublicInterface() = 0; 
    virtual void SomeMethod() = 0; 
}; 

//note: no __declspec 
class SomeClass : IPublicInterface 
{ 
    virtual ~SomeClass() { ... } 
    virtual void SomeMethod() { ... } 
}; 

//note: this is the only method which needs to be exported from the DLL 
IPublicInterface* createSomeClass() 
{ 
    return new SomeClass(); 
} 
+0

interfaz/patrón de fábrica es bueno, especialmente si va a utilizar 'GetProcAddress' y gestiona manualmente .def exportaciones tabla –

+0

Dado que la memoria está asignada en la DLL, tal vez también debería haber una' freeSomClass (IPublicInterface *) 'solo para asegúrese de que la memoria se libera correctamente? – Robert

+0

Creo que esta respuesta es incorrecta y debería eliminarse. No se puede pasar un objeto polimórfico a través de un límite de plugin, excepto cuando se usa el mismo compilador en el plugin y la aplicación. –