Pb d'appel de fonctions dans une dll c++

Résolu
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 - 11 mai 2008 à 21:15
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 12 mai 2008 à 11:40
Bonjour à tous, je vous expose mon problème.
J'essaye de créer une dll en c++ qui sera appelée à partir d'un programme en vb.

Le truc, c'est que j'aimerais appeler à partir de vb une des fonctions de la dll qui elle meme appellera une autre fonction de cette dll.

Pour faire clair, voici en gros ma dll :

extern "C"
{
   ____declspec(dllexport) void Fonction1()
   {
      Fonction2();
   }

   ____declspec(dllexport) intFonction2()
   {
      return 1;
   }
}

Or, à la compilation, j'ai ce beau message :
Fonction2 : undeclared identifier
Fonction2 : redefinition; different type modifiers

Quelqu'un aurait une idée?

18 réponses

SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
11 mai 2008 à 21:33
Si tu veux utiliser fonction2 dans fonction1, il faut que fonction2 soit définit avant fonction1 ou que son prototype soit déclaré:

extern "C"
{
    __declspec(dllexport) int Fonction2();

   __declspec(dllexport) void Fonction1()
   {
      Fonction2();
   }

   __declspec(dllexport) intFonction2()
   {
      return 1;
   }
}

P.S. __declspec prend, normalement 2 _ en préfixe pas 4.

C++ (@++)<!--
3
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
11 mai 2008 à 22:10
Effectivement ca marche, c'était tout simple en fait lol merci à toi.
En fait, je demandais ca car j'ai un problème un peu plus compliqué :
Dans ma fonction 1, j'ai une fonction 3 qui prend pour paramètre la fonction 2 :

extern "C"
{
__declspec(dllexport) intFonction2()
   {
      return 1;
   }
   __declspec(dllexport) void Fonction1()
   {
      Fonction3(Fonction2);
   }
}

Cette fonction3 est appelée à partir d'une bibliothèque extérieure et j'ai pas moyen de savoir comment elle marche (je pense qu'elle utilise des pointeurs).

Bref, quand j'appelle la fonction 1 à partir de vb, ce dernier me dit :
Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.

Une idée d'où cela peut venir ? Merci d'avance.
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
11 mai 2008 à 22:13
Quel est le prototype de Fonction3 ?

C++ (@++)<!--
0
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
11 mai 2008 à 22:24
Qu'entends-tu par prototype?
0

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

Posez votre question
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
11 mai 2008 à 22:29
Je précise qu'avec le programme c++ de base, ma fonction 3 marche tres bien..
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
11 mai 2008 à 23:03
Le prototype inclut le type de retour, le nom de la fonction, ses paramètres et autres petites choses (comme les conventions d'appel par exemple) si il y a lieu.

__declspec(dllexport) void Fonction1();

Ceci est le prototype de Fonction1.
Quel est celui de Fonction3 ?

C++ (@++)<!--
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 mai 2008 à 23:11
La convention d'appel doit être réglée direct au niveau du compilo pour ne pas faire d'erreurs (oubli de préciser ou autre), surtout si cette dll sera exploitée par différents langages.
32 bits : __stdcall
64 bits : __fastcall
La dll sera ainsi au standard de l'API Windows.

ciao...
BruNews, MVP VC++
0
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
11 mai 2008 à 23:23
-> Sakingdom : je ne connais rien de cette fonction, c'est ce qui est un peu embetant...


-> Brunews : je dois rajouter __stdcall à chaque fonction de ma dll ou seulement à celles que j'exporte?
Je l'ai ajouté à la fonction1 (celle que j'exporte) et mon erreur à changé : il me dit maintenant qu'il n'arrive pas à trouver le point d'entrée de ma fonction 1.


J'ai écrit :
extern "C"

    intFonction 2()
   {
      return 1;
   }
   __declspec(dllexport) void __stdcall Fonction1()
   {
      Fonction3(Fonction2);
   }
}

Une idée?
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
11 mai 2008 à 23:32
Tu ne connais même pas ses paramètres ? Comment fais tu pour l'utiliser. Si tu y va au pif, c'est un jeu risqué.

Ajoute __stdcall pour les fonctions exportées. On est ainsi être sûr de la façon de les appeler à partir de l'extérieur.

C++ (@++)<!--
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 mai 2008 à 23:33
Si tu ne règlers pas au niveau du compilo alors tu mets __stdcall à toutes, c'est une bonne habitude à prendre.
Tu devrais aussi compiler en mode C pour être certain de ne pas avoir de décoration sur les noms de fonction, le mieux restant d'exporter par un fichier DEF.

ciao...
BruNews, MVP VC++
0
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
12 mai 2008 à 00:05
Le problème, c'est que si je met __stdcall à toutes les fonctions, il me dit qu'il ne peut pas convertir int à  int (__cdecl *).

Tu penses que faire un fichier DEF résoudrait mon pb?

PS : ma fonction3 à la fonction 2 comme parametre, apres je ne sais pas si c'est un void, un int ou quoi...
0
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
12 mai 2008 à 00:36
Bon j'ai mis __cdecl devant ma fonction 2 et ca compile. Vb me dit maintenant : Restriction PInvoke : impossible de retourner des variants.

Sachant que ma fonction 2 est du type unsigned char et retourne un booleen, est-ce que c'est ma fonction1, qui est un void, qui poserait problème?


Pour mémoire, j'ai :


unsigned char __cdecl Fonction 2(xx a,xx b)
{
   return Bool;
}

__declspec(dllexport)  void __stdcall Fonction 1()
{
   Fonction3(Fonction2)
}


Savez-vous d'ou peut venir le problème? Merci
0
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
12 mai 2008 à 10:42
Bon, ça marche pas vraiment avec __stdcall,. En effet, si je met ça :
__declspec(dllexport)  int __stdcall Fonction 1()
{
   return 1;
}
et que j'appelle la fonction 1 dans vb, il me dit qu'il n'arrive pas à trouver le point d'entrée de cette fonction. Comment faire?
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
12 mai 2008 à 11:03
Regarde mes sources, il y a plusieurs exemples de DLLs pour VB.

Supprime cela: __declspec(dllexport)
et exporte via un fichier DEF.

ciao...
BruNews, MVP VC++
0
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
12 mai 2008 à 11:06
Ok merci, je vais essayer ca. Est-ce que je dois mettre le .DEF dans le debug de mon projet vb?
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
12 mai 2008 à 11:20
Le DEF s'inscrit ici:
Onglet Linker => Input => Module Definition File

VB ignore tout de la fabrication de la DLL utilisée donc il se fout du DEF comme du reste.

ciao...
BruNews, MVP VC++
0
psychospire Messages postés 42 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 9 décembre 2008 1
12 mai 2008 à 11:26
Bon, je ne vois vraiment pas d'ou peut venir le problème... j'ai fais le fichier DEF comme ca :
LIBRARY "MaDll.dll"
EXPORTS
Function1 [mailto:_Function1@0 _Function1@0]

j'ai ma dll :
extern "c"
{
   int __stdcall Function1
   {
      return 1;
   }
}

et j'appelle ma fonction1 dans vb comme ca :
Private

Declare
Function Function1 
Lib
"MaDll.dll" ()
As
Integer

Et il ne trouve tjrs pas le point d'entrée...
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
12 mai 2008 à 11:40
Pourquoi tu ne regardes pas ce qu'on publie ???
Promis, c'est pas pour décorer le site....

LIBRARY MaDll
EXPORTS
  Function1    @1
  Function2    @2
etc....

ciao...
BruNews, MVP VC++
0
Rejoignez-nous