Access violation à l'appel de DLL
Salut à vous
J'ai aussi ce type de pb de violation d'accès lorsque j'appelle une méthode de ma dll.
J'ai développé des plugins (des .dll sous win32) que je souhaite charger dynamiquement dans mon appli de test.
Tous mes plugins sont basés sur une même interface Plugin.h, que j'ai déclaré comme tel :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#ifndef _PLUGIN_H_
#define _PLUGIN_H_
# ifdef WIN32_DLL
# define WIN32_PLUGIN_API __declspec(dllexport)
# else
# define WIN32_PLUGIN_API
# endif
#include "../DeviceManager.h"
class WIN32_PLUGIN_API Plugin {
public:
/*my virtual methods to be redefined*/
};
/*!
* \Class PluginFactory
*
* PluginFactory just contains informations concerning a plugin
* It's separated from the Plugin class to make the disctinction between the informations of the plugin and the communication methods
*
*/
class WIN32_PLUGIN_API PluginFactory {
public:
virtual std::string getPluginName()=0;
virtual std::string getPluginVersion()=0;
virtual std::string getPluginAuthor()=0;
virtual Plugin *getInstance(DeviceManager *controller)=0;
};
extern "C" {
WIN32_PLUGIN_API PluginFactory* createFactory();
}
#endif //_PLUGIN_H_ |
J'ai donc compilé mes plugins en utilisant l'option WIN32_DLL et généré les dll correspondantes.
Jusque là tout va bien je pense...
Je souhaite donc utiliser l'explicit linking pour charger mes plugins dans mon appli de test.
Au démarrage je charge mes dlls dans le but de remplir une map<pluginName, pluginInstance> ...
Mais voilà au premier appel à la méthode de plugin qui doit me retourner le nom du plugin (pluginFactory->getPluginName()) : violation d'accès.
Voilà le code qui charge les plugins :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#ifdef _WIN32
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#else
#include <dirent.h>
#include <dlfcn.h>
#endif
typedef PluginFactory* (*OpCreation)();
/****************************************/
//PluginFactories
#ifdef _WIN32
void PluginFactories::loadPlugins(std::string path) {
//std::string dllpath = path + "\\*.dll";
WIN32_FIND_DATA File;
HANDLE liste;
TCHAR szDir[MAX_PATH];
size_t length_of_arg;
StringCchLength(path.data(), MAX_PATH, &length_of_arg);
StringCchCopy(szDir, MAX_PATH, path.data());
StringCchCat(szDir, MAX_PATH, TEXT("\\*.dll"));
liste = FindFirstFile(szDir, &File);
if(liste == INVALID_HANDLE_VALUE)
std::cerr << "FindFirstFile failed" << std::endl;
do {
std::string tmp = path + "\\" + (std::string)File.cFileName;
std::cout << tmp << std::endl;
HINSTANCE lib = LoadLibrary(tmp.c_str());//charge le plugin
if (!lib) {
std::cerr << "LoadLibrary failed: " << GetLastError() << std::endl;
continue;
}
OpCreation createFactory = (OpCreation) GetProcAddress(lib, "createFactory");//lie la dll au symbole
if (!createFactory) {
std::cerr << "GetProcAddress failed: " << GetLastError();
continue;
}
PluginFactory *pluginFactory = (*createFactory)();
if (!pluginFactory) {
continue;
}
factories[pluginFactory->getPluginName()] = pluginFactory;
} while ((FindNextFile(liste, &File)));
// FindClose() ferme la recherche
FindClose(liste);
} |
Avant de travailler sous VC++ 2008 express , j'utilisais un Makefile et là surprise tout fonctionne !
Je pense donc que ca vient d option de compil et j'ai comparé celles de mon Makefile (c à dire aucune à part /EHsc et /W3) et celle des lignes de commande de vc++ (yen a bcp). J'ai donc retiré une à une les options dans vc++ pour que les lignes de commande ressemblent à celle de mon Makefile.
Rien y fait :(
J'ai abso besoin de ce proj vc++ et ne sais pas comment faire, y aurait il d'autre chose à activer dans vc++ pour utiliser d dll dynamiquement ?
Merci d'avance pour vos réponses
et désolé pour le roman mais j'essaye d'être le plus précis possible.
Access violation à l'appel de DLL
Je te conseillerais d'éviter les std::string dans l'interface d'une DLL (et tous les types de la STL, en fait).
Tu auras moins de problèmes en retournant un char*, ou si tu es familier avec COM, une BSTR.
Essaie aussi d'utiliser le debugger pour en savoir plus sur le plantage (notamment la stack trace).