Pointeur de fonction : multi-appels

Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 - 22 janv. 2005 à 16:58
racpp Messages postés 1910 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 - 25 janv. 2005 à 00:12
Bonjour tout le monde,

Les pointeurs de fonction me posent problême!! sniff!! En fait, j'ai un pointeur de fonction pointant sur une fonction se trouvant dans une DLL! Ce pointeur fonctionne!! J'arrive à appeller la fonction...le soucis, c'est que lorsqu'avec le même pointeur j'essaie de lancer la même fonction, la fonction n'est pas executée!! Que faire dans un tel cas ??

Gendal67, Dev-C++ 4.9.9.1, J'adore cppfrance!! :-))

14 réponses

dletozeun Messages postés 546 Date d'inscription vendredi 13 février 2004 Statut Membre Dernière intervention 9 janvier 2008 1
22 janv. 2005 à 22:21
tu veux dire que la premiere fois ca marche mais la deuxieme fois que t'appelle la fonction ca marche pas?
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
22 janv. 2005 à 23:19
Oui c'est exactement ça!! Et c'est pas la première fois que ça me le fait en fait...:s

Gendal67, Dev-C++ 4.9.9.1, J'adore cppfrance!! :-))
0
racpp Messages postés 1910 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 15
23 janv. 2005 à 01:31
Salut,
Tu n'as pas oublié la convention d'appel de la fonction? Si oui, voici un exemple d'utilisation d'un pointeur de fonction avec convention d'appel WINAPI:
typedef BOOL (WINAPI *PFonction) ( int, char);
PFonction MaFonction;
MaFonction=(PFonction)GetProcAddress(hDLL,"fonction");
Par défaut le compilateur (comme visual c) ajoute la convention "__cdecl" qui pourrait causer des plantages ou anomalies si la fonction utilise une autre convention (WINAPI = __stdcall). En général, les DLLs utilisent WINAPI.
Il est possible que ton problème viendrait de là.
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
23 janv. 2005 à 10:59
Eh bien c'est fort probable en effet, mais j'ai essayé avec WINAPI et cela ne donne rien de +...la fonction est URLDownloadToFile() .... il semble sur msdn qu'elle n'est pas d'étiquette (WINAPI, CALLBACK, etc...) précise....une idée ??

Gendal67, Dev-C++ 4.9.9.1, J'adore cppfrance!! :-))
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
23 janv. 2005 à 11:01
#define LPBINDSTATUSCALLBACK DLGPROC
#define MAX_DOWNLOAD_PAGES 50


typedef HRESULT (WINAPI *DOWNLOAD) (LPUNKNOWN, LPCTSTR, LPCTSTR, DWORD, LPBINDSTATUSCALLBACK);
DOWNLOAD pDown;

// instructions

bool Initialize() {

hDll = LoadLibrary("urlmon.dll");

if(!hDll) return false;

pDown = (DOWNLOAD) GetProcAddress(hDll, "URLDownloadToFileA");

if(!pDown) return false;

//instructions...
}

Si cela peut t'aider....

Gendal67, Dev-C++ 4.9.9.1, J'adore cppfrance!! :-))
0
racpp Messages postés 1910 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 15
23 janv. 2005 à 19:03
Salut,
L'erreur est certainement ailleurs dans ton code. Toutes les fonctions des DLLs de Windows sont en WINAPI. Voici un petit exemple permettant de télécharger 3 pages l'une après l'autre de 3 sites différents:
typedef HRESULT (WINAPI *DOWNLOAD) (LPUNKNOWN, LPCTSTR, LPCTSTR, DWORD, LPBINDSTATUSCALLBACK);
HINSTANCE hDll = LoadLibrary("urlmon.dll");
DOWNLOAD pDown= (DOWNLOAD) GetProcAddress(hDll, "URLDownloadToFileA");
CoInitialize(0);
HRESULT err=pDown(0,"http://www.google.fr/index.html","c:\\google.txt",0,0);
err=pDown(0,"http://www.voila.fr/index.html","c:\\voila.txt",0,0);
err=pDown(0,"http://www.yahoo.fr/index.html","c:\\yahoo.txt",0,0);
CoUninitialize();
FreeLibrary(hDll);
Je viens de le tester, et ça marche parfaitement.
Petite remarque: si tu veux intercepter les événements de progression ou de la fin du téléchargement (etc...), le dernier paramètre de "URLDownloadToFileA" doit être un pointeur sur une interface "IBindStatusCallback" définie dans ton programme sous forme de classe. Si ça t'intéresse, je posterai ici un exemple de cette petite classe.
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
23 janv. 2005 à 19:37
Non pour le truc de la classe....mais ça me tue que chez moi cela ne marche pas (jamais d'ailleurs)!! Jte montre mon code, pourrais tu y trouver l'erreur ? :

#include <windows.h>
#include <stdio.h>


#define LPBINDSTATUSCALLBACK DLGPROC
#define MAX_DOWNLOAD_PAGES 50


typedef HRESULT (WINAPI *DOWNLOAD) (LPUNKNOWN, LPCTSTR, LPCTSTR, DWORD, LPBINDSTATUSCALLBACK);

DOWNLOAD pDown;


char szPath[MAX_PATH];
HINSTANCE hDll;


bool Initialize();


DWORD WINAPI ScanWeb(LPVOID pv) {

static int nbThread = 0;

if(nbThread > MAX_DOWNLOAD_PAGES) return 0L;

nbThread++;

char szURL[MAX_PATH];
lstrcpy(szURL, (char*) pv);

char szFile[MAX_PATH];
GetName(szFile);

pDown(0, szURL, szFile, 0, 0);

nbThread--;
return 0L;
}

bool Initialize() {

hDll = LoadLibrary("urlmon.dll");

if(!hDll) return false;

pDown = (DOWNLOAD) GetProcAddress(hDll, "URLDownloadToFileA");

if(!pDown) return false;

return true;
}

Gendal67, Dev-C++ 4.9.9.1, J'adore cppfrance!! :-))
0
racpp Messages postés 1910 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 15
24 janv. 2005 à 02:12
Je pense que tu n'as pas bien vu les deux fonctions CoInitialize() et CoUninitialize() dans mon exemple. Désolé pour la présentation que je n'arrive plus à soigner dans cette nouvelle version du forum. Comment tu fais toi?
La fonction URLDownloadToFile() est cencée fonctionner avec les Activex et les interfaces. C'est pour cela qu'il est obligatoire d'initialiser la librairie COM avec CoInitialize() avant de l'utiliser. Voici un exemple avec ton code comme noyau. Et ça marche aussi:
#include <windows.h>
#include <stdio.h>

#define LPBINDSTATUSCALLBACK DLGPROC
#define MAX_DOWNLOAD_PAGES 50

typedef HRESULT (WINAPI *DOWNLOAD) (LPUNKNOWN, LPCTSTR, LPCTSTR, DWORD, LPBINDSTATUSCALLBACK);

DOWNLOAD pDown;

char szPath[MAX_PATH];
HINSTANCE hDll;

void GetName(char *File)
{
static int compt=0;
if (compt==0) strcpy(File,"c:\\google.txt");
if (compt==1) strcpy(File,"c:\\voila.txt");
if (compt==2) strcpy(File,"c:\\yahoo.txt");
compt++;
return;
}

DWORD WINAPI ScanWeb(LPVOID pv) {
  
  static int nbThread = 0;
  
  if(nbThread > MAX_DOWNLOAD_PAGES) return 0L;
  
  nbThread++;
  
  char szURL[MAX_PATH];
  lstrcpy(szURL, (char*) pv);
  
  char szFile[MAX_PATH];
  GetName(szFile);
  
  pDown(0, szURL, szFile, 0, 0);
    
  nbThread--;
  return 0L;    
 }
 
bool Initialize() {
  
  hDll = LoadLibrary("urlmon.dll");
  
  if(!hDll) return false;
  
  pDown = (DOWNLOAD) GetProcAddress(hDll, "URLDownloadToFileA");
   
  if(!pDown) return false;
  
  return true; 
 }

int main()
{
CoInitialize(0);
bool ret=Initialize();
char url[MAX_PATH];
strcpy(url,"http://www.google.com/index.html");
ScanWeb((LPVOID)url);
strcpy(url,"http://www.voila.fr/index.html");
ScanWeb((LPVOID)url);
strcpy(url,"http://www.yahoo.fr/index.html");
ScanWeb((LPVOID)url);
FreeLibrary(hDll);
CoUninitialize();
return 0;
}

J'espère que cette fois la présentation sera meilleure.
0
racpp Messages postés 1910 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 15
24 janv. 2005 à 02:21
Franchement cette nouvelle version du forum ne me plait pas du tout. Même le bouton "Ajouter" refuse souvent de répondre. J'espère que ce sera réglé très bientôt.
0
racpp Messages postés 1910 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 15
24 janv. 2005 à 02:53
Le problème de présentation a eté causé par mon navigateur Opera qui ne supporte pas bien cette nouvelle version du forum. Sous Internet Explorer c'est génial, je vois même les barres d'outils qui n'apparaissent pas dans Opera. Je renvois de nouveau ma réponse.
Je pense que tu n'as pas bien vu les deux fonctions CoInitialize() et CoUninitialize() dans mon exemple. Désolé pour la présentation que je n'arrivais pas à soigner . La fonction URLDownloadToFile() est cencée fonctionner avec les Activex et les interfaces. C'est pour cela qu'il est obligatoire d'initialiser la librairie COM avec CoInitialize() avant de l'utiliser. Voici un exemple avec ton code comme noyau. Et ça marche aussi:
#include <windows.h>
#include <stdio.h>
#define LPBINDSTATUSCALLBACK DLGPROC
#define MAX_DOWNLOAD_PAGES 50
typedef HRESULT (WINAPI *DOWNLOAD) (LPUNKNOWN, LPCTSTR, LPCTSTR, DWORD, LPBINDSTATUSCALLBACK);
DOWNLOAD pDown;
char szPath[MAX_PATH];
HINSTANCE hDll;
void GetName(char *File)
{
static int compt=0;
if (compt==0) strcpy(File,"c:\\google.txt");
if (compt==1) strcpy(File,"c:\\voila.txt");
if (compt==2) strcpy(File,"c:\\yahoo.txt");
compt++;
return;
}
DWORD WINAPI ScanWeb(LPVOID pv)
{
static int nbThread = 0;
if(nbThread > MAX_DOWNLOAD_PAGES) return 0L;
nbThread++;
char szURL[MAX_PATH];
lstrcpy(szURL, (char*) pv);
char szFile[MAX_PATH];
GetName(szFile);
pDown(0, szURL, szFile, 0, 0);
nbThread--;
return 0L;
}
bool Initialize()
{
hDll = LoadLibrary("urlmon.dll");
if(!hDll) return false;
pDown = (DOWNLOAD) GetProcAddress(hDll, "URLDownloadToFileA");
if(!pDown) return false;
return true;
}
int main()
{
CoInitialize(0);
bool ret=Initialize();
char url[MAX_PATH];
strcpy(url,"http://www.google.com/index.html");
ScanWeb((LPVOID)url);
strcpy(url,"http://www.voila.fr/index.html");
ScanWeb((LPVOID)url);
strcpy(url,"http://www.yahoo.fr/index.html");
ScanWeb((LPVOID)url); FreeLibrary(hDll);
CoUninitialize();
return 0;
}
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
24 janv. 2005 à 17:43
Oki oki, mais j'un encore un pti souci : 'undefined reference to [mailto:'CoInitialize@4' 'CoInitialize@4']
Faut mettre quelle lib avec ??

Gendal67, Dev-C++ 4.9.9.1, J'adore cppfrance!! :-))
0
racpp Messages postés 1910 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 15
24 janv. 2005 à 18:13
Sous Visual C, tu n'as rien à ajouter. Il suffit juste ce copier l'exemple puis le coller dans un nouveau projet console. Pour les autres compilateurs : aucune idée.
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
24 janv. 2005 à 18:27
Oui!!!! En mode console ça marche!!! Mais quel interet maintenant de l'avoir en mode console??? ... ya pas moyen de faire du GUI avec ??

Gendal67, Dev-C++ 4.9.9.1, J'adore cppfrance!! :-))
0
racpp Messages postés 1910 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 15
25 janv. 2005 à 00:12
Ca marche aussi en GUI. J'avais testé le premier exemple dans un de mes projets avec fenêtres et tout. Ca devrait être un truc simple que tu pourrais régler sur Dev c++ pour que tout rentre dans l'ordre.
0