2008-09-21 9 views
13

Quelle est la méthode correcte pour importer une classe C++ à partir d'une DLL? Nous utilisons Visual C++.Importation dynamique d'une classe C++ à partir d'une DLL

Il existe le trileta dllexport/exports.def + LoadLibrary + GetProcAddress, mais il ne fonctionne pas sur les classes C++, mais seulement sur les fonctions C. Est-ce dû à C++ name-mangling? Comment puis-je faire ce travail?

Répondre

2

Je déclare normalement une classe de base d'interface, utilise cette déclaration dans mon application, puis utilise LoadLibrary, GetProcAddress pour obtenir la fonction d'usine. Le facteur renvoie toujours le pointeur du type d'interface.

Voici un exemple pratique, exporting an MFC document/view from a DLL, chargé dynamiquement

1

travaux dllexport/dllimport, placez-le avant votre nom de classe dans le fichier d'en-tête et vous êtes bon pour aller.

Typiquement, vous voulez utiliser dllexport dans la DLL, et dllimport dans l'exe (mais vous pouvez simplement utiliser dllexport partout et cela fonctionne, en le faisant «juste» le rend un peu plus rapide à charger).

De toute évidence, cela concerne la compilation de liens. Vous pouvez utiliser la directive de l'éditeur de liens/delayload pour la rendre 'dynamique', mais ce n'est probablement pas ce que vous voulez de la ligne d'objet.

Si vous voulez vraiment un chargement de style LoadLibrary, vous allez devoir envelopper vos fonctions C++ avec des wrappers "extern C". Le problème est dû au mangling de noms, vous pouvez taper le nom entièrement modifié et cela fonctionnera. Les solutions de contournement sont généralement de fournir une fonction C qui renvoie un pointeur vers la classe correcte - COM fonctionne de cette façon, car il exporte 4 fonctions C d'une DLL qui sont utilisées pour obtenir les méthodes d'interface à l'intérieur de l'objet dans la DLL. .

12

Vous devez ajouter ce qui suit:

extern "C" 
{ 
... 
} 

pour éviter la fonction mutiler.

vous pourriez envisager d'écrire deux fonctions simples C:

SomeClass* CreateObjectInstace() 
{ 
    return new SomeClass(); 
} 

void ReleaseObject(SomeClass* someClass) 
{ 
    delete someClass; 
} 

En utilisant uniquement les fonctions que vous pouvez ensuite ajouter/fonctionnalité de changement de votre création/suppression objet. Ceci est parfois appelé une usine.

+1

Ces noms 'SomeClass' ne devraient-ils pas avoir des astérisques (c'est-à-dire des pointeurs vers' SomeClass')? –

2

Découvrez this question. Fondamentalement, il y a deux façons. Vous pouvez marquer la classe en utilisant _dllexport puis lier avec la bibliothèque d'importation, et la DLL sera chargée automatiquement. Ou si vous voulez charger dynamiquement la DLL, vous pouvez utiliser l'idée de fonction d'usine que @titanae a suggérée

Questions connexes