2009-10-04 11 views

Répondre

3

répondre à votre question strictement, vous devez ajouter une extern fonction « C » qui renvoie le résultat du constructeur:

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

Ensuite, dans votre source, vous pouvez utiliser GetProcAddr sur « new_foo » pour appeler la fonction .

3

Vous devrez exporter une fonction de la DLL qui appelle le constructeur et retourner le nouvel objet. Essayez d'éviter d'utiliser des types C++ concrets comme paramètres de fonction; L'idée des DLL est que vous pouvez les mettre à jour de manière indépendante, mais un compilateur mis à jour peut présenter différemment std :: string, ce qui provoque une incompatibilité lors de l'exécution. C'est ce qui est à la base de COM, par exemple - un système de type limité et une fonction exportée standard pour obtenir des instances d'objets.

+0

Tt semble que la source de la DLL n'est pas sous son contrôle. –

+0

La source DLL est sous mon contrôle – SomeUser

+0

Si la classe est destinée à être utilisée, elle devrait probablement déjà être compilée avec __declspec (dllexport), donc il suffit de convaincre le fichier d'en-tête de mettre __declspec (dllimport) dans le définition de classe. Sinon, vous pouvez toujours modifier le fichier d'en-tête vous-même. – JesperE

10

Vous devez déclarer votre classe à l'aide du mot clé __declspec(dllexport) lors de la création de la DLL. Lorsque vous utilisez la DLL, la classe doit être déclarée avec __declspec(dllimport):

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

class DECLSPEC_CLASS MyClass 
{ 
... 
} 

Lorsque la DLL est compilé, vous devez ajouter -DCOMPILING_DLL à la liste des defines. Lorsque vous utilisez la classe, vous devez établir un lien statique avec la DLL, c'est-à-dire transmettre la bibliothèque d'importation mydll.lib au programme principal.

Si vous souhaitez charger la DLL à l'exécution, vous devez avoir une fonction C dans la DLL qui crée un objet et le renvoie pour vous. Il n'existe aucun moyen de rechercher dynamiquement un constructeur dans une DLL (en utilisant GetProcAddress()).

+1

Pouvez-vous citer une source pour la dernière déclaration? AFAIK a ctor a un nom tronqué, et vous pouvez appeler GetProcAddress en utilisant ce nom. Qu'est-ce qui t'arrêterait? – MSalters

+0

Oui, techniquement vous avez raison. – JesperE

3

Au lieu d'exporter toutes les méthodes de la classe en utilisant __declspec, vous pouvez également compter sur le fait que le compilateur peut invoquer des fonctions virtuelles via le vtable, donc par exemple:

//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

interface/modèle d'usine est agréable, surtout si vous allez utiliser 'GetProcAddress' et géré manuellement .def exporte la table –

+0

Puisque la mémoire est allouée dans la DLL, peut-être il devrait aussi y avoir une' freeSomClass (IPublicInterface *) 'juste pour Assurez-vous que la mémoire est libérée correctement? – Robert

+0

Je pense que cette réponse est fausse et devrait être supprimée. Vous ne pouvez pas passer un objet polymorphe à travers une limite de plugin, sauf si le même compilateur est utilisé dans le plugin et l'application. –

Questions connexes