IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Visual C++ Discussion :

Chargement d'une DLL perso mais echec du GetProcAddress


Sujet :

Visual C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 3
    Par défaut Chargement d'une DLL perso mais echec du GetProcAddress
    Bonjour a tous, voyez l'heure tardive a laquelle je vous parle et pour cause, je suis au japon pour l’été.
    Je suis débutant en C++, langage que j'ai appris principalement par moi-même grâce a des tutoriels notamment.

    J'ai pour projet de créer une GUI modulable a l'aide de DLL, pour qu'elle puisse gérer différents types de données. Je n'en suis pas encore la, j'en suis a la découverte du chargement dynamique des DLL. (j'ai déjà réussi a en charger par référence et tout le bazar)

    Et donc mon problème est que la bibliothèque est bien chargée avec le LoadLibrary mais que les deux GetProcAddress censés charger les deux fonctions de ma DLL échouent et me renvoi l'erreur 127 (GetLastError): The specified procedure could not be found. (information précise, utile et pertinente n'est-ce pas -_-")

    Donc, je me suis mis en quête un peu partout sur le net et sur ce forum en particulier d'information relative a mon problème, j'imagine qu'il y en a, mais bien que j’ai beaucoup cherche je n'ai rien trouve qui colle parfaitement a ma situation alors j'ai décide de créer un post. Je vous donne le code de ma DLL et la partie de mon main ou je charge la dll pour que vous puissiez m'aider au mieux: (je vous épargne les commentaires dont mes fichiers sont truffes étant donne que j'ai construit ces fichiers pour émailler un tutoriel)

    1stDLL.h (qui est copie dans le répertoire de mon programme client)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    #ifndef __HEADER__1ST_DLL__ 
    #define __HEADER__1ST_DLL__
     
    #include <windows.h> 
    #include <tchar.h> 
     
    namespace GUIMaker
    {
    	#ifdef  __cplusplus
    		extern "C" {
    	#endif
    	__declspec(dllexport) HWND BuildButton( HINSTANCE hInstance,
    											HWND parent, 
    											TCHAR* text,
    											int msg,
    											int HPos = 0,
    											int VPos = 0, 
    											int bWidth = 100, 
    											int bHeight = 30);
     
    	__declspec(dllexport) HWND BuildWindow( HINSTANCE hInstance, 
    											HWND parent, 
    											TCHAR* title, 
    											DWORD additionalCaract = 0, 
    											int HPos = 100, 
    											int VPos = 0, 
    											int wWidth = 600, 
    											int wHeight = 600);
     
    	#ifdef  __cplusplus
    					}
    	#endif
    }
     
    #endif
    1stDLL.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    67
    68
     
    #include "1stDLL.h"
     
    HWND GUIMaker::BuildButton( HINSTANCE hInstance,
    							HWND parent, 
    							TCHAR* text,
    							int msg,
    							int HPos,
    							int VPos, 
    							int bWidth, 
    							int bHeight)
    {
    	HWND button = CreateWindow( _T("BUTTON"), 
    								text, 
    								WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD, 
    								HPos, 
    								VPos, 
    								bWidth, 
    								bHeight, 
    								parent, 
    								(HMENU)msg,
    								hInstance, 
    								NULL);
     
    	return button;
    }
     
    HWND GUIMaker::BuildWindow( HINSTANCE hInstance, 
    							HWND parent,
    							TCHAR* title,
    							DWORD additionalCaract,
    							int HPos, 
    							int VPos,
    							int wWidth,
    							int wHeight)
    {
     
    	HWND window;
    	if (additionalCaract != 0)
    	{
    	window = CreateWindow(  _T("STATIC"),
    							title,
    							WS_VISIBLE | additionalCaract,
    							HPos,
    							VPos,
    							wWidth,
    							wHeight,
    							parent, 
    							NULL,
    							hInstance,
    							NULL);
    	}
     
    	else window = CreateWindow( _T("MDICLIENT"), 
    								title,
    								WS_VISIBLE | WS_OVERLAPPEDWINDOW,
    								HPos,
    								VPos,
    								wWidth,
    								wHeight,
    								parent,
    								NULL,
    								hInstance,
    								NULL);
     
    	return window;
     
    }
    enfin le bout de code ou j'essaie de charger dynamiquement mes fonctions dans mon fichier Exercise2.cpp (mon fichier MyDLL.dll seul se trouve dans le dossier C:/Windows/sysWOW64/ peut-être que ça a son importance)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include "1stDLL.h"
     
    [...]
     
    typedef HWND (CALLBACK* DLLFUNC1)(HINSTANCE, HWND, TCHAR*, DWORD, int, int, int, int); // for BuildWindow function
    typedef HWND (CALLBACK* DLLFUNC2)(HINSTANCE, HWND, TCHAR*, int, int, int, int, int); // for BuildButton function
     
    [...]
     
    	//loading the DLL and its 2 functions
     
    	 DLLFUNC1 DLLFunc1;			// Function pointer for BuildWindow function
    	 DLLFUNC2 DLLFunc2;		    // Function pointer for BuildButton function
     
    	HMODULE hDLL = LoadLibrary( _T("MyDLL.dll") );
     
    	if (hDLL != NULL)
    	{
    	   DLLFunc1 = (DLLFUNC1) GetProcAddress( hDLL, "GUIMaker::BuildWindow");
    	   DLLFunc2 = (DLLFUNC2) GetProcAddress( hDLL, "GUIMaker::BuildButton");
    	   DWORD problem = GetLastError();
     
    	   if (!DLLFunc1)
    	   {
    		  // handle the error
    		  FreeLibrary(hDLL); 
    		  return NULL;
    	   }
    	   if (!DLLFunc2)
    	   {
    		  // handle the error
    		  FreeLibrary(hDLL);       
    		  return NULL;
    	   }
    	   else
    	   {
    		HWND Question = DLLFunc1(   hInstance,
    									hWnd,
    									SURPRISE,
    									WS_CHILD,
    									105,
    									130,
    									300,
    									50);
     
    		HWND YesButton = DLLFunc2(  hInstance, 
    									hWnd,
    									_T("Yes"),
    									WM_YESBUTTON,
    									200,
    									200,
    									100,
    									30);
     
    		FreeLibrary(hDLL);
    		}
     
    	}
    PS: j'ai défini WM_YESBUTTON dans mon fichier ressource, idem pour SURPRISE, le problème ne vient pas d'eux puisque ce code marche dans un autre projet ou j'ai utilise les références pour linker ma DLL

    PS2: pour le code de chargement dynamique je me suis servis de la documentation officielle de VC++ 2010 express sur msdn.microsoft.com/chaipuquoi

    PS3(comme ça j'ai fait toute la famille ^-^): désolé pour l'indentation ratée par le Ctrl+C Ctrl+V j'ai la flemme de la refaire a la main et désolé pour le manque d'accent dans mon texte, je travaille sur un clavier Mac et je connais pas les raccourcis

  2. #2
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 3
    Par défaut
    J'ai une question en particulier, j'ai essaye pas mal de scenario d'erreur (mangling, ...) et ma dernière idée en date serait un problème venant de la surcharge de mes fonctions alors je voudrais avoir votre avis, est-ce que le fait d'avoir mis des valeurs par défaut a certains paramètres de mes fonctions peut avoir fait foirer le GetProcAddress puisqu'il y aurait alors plusieurs fonctions avec le même non ?

    EDIT: j'ai essaye en modifiant .h et .cpp de MyDLL pour n'avoir plus que des fonctions non surchargées et ça ne marche pas non plus

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 3
    Par défaut
    Bon, après une petite demi-douzaine d'heure(plus toute la journée d'hier a peu près -_-) passées sur le problème, j'ai trouve une solution:

    -ne plus utiliser de namespace (ça marche avec mais en appelant la fonction sans le préfixe du namespace et je ne sais pas pourquoi donc par prudence je ne l'utilise plus)(mais je veux bien une explication si qqn en connait une)

    -ne plus surcharger les fonctions (la aussi ça marche et je ne sais pas pourquoi)(idem pour l'explication je suis preneur)

    -mais SURTOUT j'ai change la déclaration de mes pointeurs récupérant les fonctions de la DLL avec le préfixe __cdelc car apparemment le problème venait du fait qu’étant déclares en __stdcall et vu le nombre et la taille des paramétrés en entrée des fonctions de la DLL, dépassant la taille prévue par le __stdcall, le compileur a corrige de lui-même implicitement la déclaration des fonctions dans la DLL en tant que __cdelc et mes pointeurs étant déclarés en tant que __stdcall, ils étaient incompatibles et cela provoquait l'erreur:
    The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
    (NDR: j'ai trouve cette erreur après avoir supprime le namespace ET conjointement la surcharge de fonction)(Merci Google pour m'avoir souffle la solution)

    code du client: (je vous laisse le soin d'imaginer les changements très simples du .h de la DLL)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Declaration of the DLL exported function type
    typedef HWND (CDECL* DLLFUNC1)(HINSTANCE, HWND, TCHAR*, int, int, int, int, int); // for BuildButton function
    typedef HWND (CDECL* DLLFUNC2)(HINSTANCE, HWND, TCHAR*, DWORD, int, int, int, int); // for BuildWindow function

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VB] Problème de chargement d'une DLL
    Par Elijha dans le forum Windows Forms
    Réponses: 3
    Dernier message: 10/05/2006, 09h24
  2. Chargement d'une DLL
    Par olive_le_malin dans le forum MFC
    Réponses: 15
    Dernier message: 16/12/2005, 17h09
  3. Réponses: 4
    Dernier message: 03/11/2005, 13h57
  4. Contexte de chargement d'une DLL
    Par Guillemot dans le forum Windows
    Réponses: 2
    Dernier message: 10/07/2005, 09h34
  5. Chargement d'une DLL et utilisation du multithread
    Par Maitre Kanter dans le forum Langage
    Réponses: 6
    Dernier message: 07/09/2004, 23h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo