Précédent   Forum des professionnels en informatique > Logiciels > Microsoft Office > Général VBA
Général VBA Forum général VBA . Pour les logiciels spécifiques (Access, Excel, Word, ...), postez dans les bons sous forums.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/03/2006, 12h46   #1
Invité régulier
 
Inscription : mars 2006
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 24
Points : 6
Points : 6
Par défaut [VBA]dll C++ : erreur 49 et 453

Bonjour,
je peine depuis quelques jours à créer une dll en c++ qui puisse être appelée depuis VBA. J'ai bien sûr trouvé quelques exemples de code qui marchent, mais je n'arrive pas à transposer ces exemples dans mon propre code pour le faire fonctionner.
Voici mon problème, en détail :
Avec Code::Blocks (et sous Windows XP), je génère** une dll "TestDLL.dll" dont le code est le suivant :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
void __stdcall SomeFunction(const LPCSTR sometext)
{
    MessageBox(0, sometext , "DLL Message", MB_OK | MB_ICONINFORMATION);
}
#ifdef __cplusplus
}
#endif
Lors de la compilation, je demande à Code::Blocks (Project>Properties>Targets) de créer un fichier .def.
Celui-ci, que Code::Blocks appelle libTestDLL.def, contient les lignes suivantes :

EXPORTS
SomeFunction@4 @1

Dans VBA, j'appelle la dll de la sorte :

Code :
1
2
3
4
5
 
Private Declare Sub SomeFunction Lib "C:\Documents and Settings\...\TestDLL8\TestDLL.dll" (ByVal chaine As String)
Sub Test()
SomeFunction ("toto")
End Sub
Et là : erreur 453 (point d'entrée de la fonction introuvable)!

Bien sûr, dll et fichier def sont dans le même dossier. Bien sûr, j'ai essayé de modifier le fichier .def, en changeant son nom (en TestDLL.def)ou en modifiant son contenu. Par exemple :

LIBRARY TestDLL
EXPORTS
SomeFunction=SomeFunction@4 @1;

Je pense avoir essayé toutes les combinaisons de variantes imaginables...
J'ai également vérifié avec Quick View Plus 8.0 que SomeFunction@4 est bien le nom de la fonction telle qu'elle apparaît dans la table d'exportation de la dll.

En ce qui concerne le code c++, c'est celui qu'un forumeur m'a conseillé de prendre après mes vaines tentatives avec des fichiers .h. Ses conseils me semblent de bon aloi, car son exemple de dll est en fait le seul qui marche (sans que je sache pourquoi...).

Maintenant, il y a plus surprenant : lorsque je supprime le __stdcall (j'écris "void SomeFunction(const LPCSTR sometext)"), alors le code commence par fonctionner correctement (j'ai un petit mesage "toto"), puis juste après une erreur 49 (convention d'appel incorrecte).

C'est donc soit l'une (erreur 453), soit l'autre (erreur 49). J'aimerai assez sortir de ce dilemme!

Bien cordialement, et en vous remerciant par avance pour votre aide,

EL

** Pour générer une dll avec Code::Blocks, je crée un nouveau projet (New Project>Dynamic Library File) en spécifiant de ne pas créer de nouveaux fichiers (option "Do not create any files"). J'importe alors dans ce projet le fichier TestDLL.cpp contenant le code ci-dessus. Je nomme le projet TestDLL et spécifie (Project>Properties>Targets) que le nom de la dll en sortie doit être TestDLL.dll.
EL0807 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 13h26   #2
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125
Avant d'aller plus loin :
Une fonction retourne une valeur et le type de cette valeur doit donc être défini.

Je vais donc m'abstenir de commenter la fonction elle même (c'est du C et elle n'a rien à voir avec ce forum : VB).
Je ne puis que t'inviter, dans ces conditions, à t'interroger en tout 1er lieu (qu'il s'agisse de ta fonction ou de toute autre fonction) sur le fonctionnement de la déclaration d'une .dll
Nous te répondrons avec plaisir une fois passé ce cap d'étude et de compréhension indispensable.
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 14h16   #3
Invité régulier
 
Inscription : mars 2006
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 24
Points : 6
Points : 6
Cher ami,

il serait bon parfois que les informaticiens daignent descendre de leurs hauteurs pour s'adresser de manière intelligible à la plèbe!

Si les seuls conseils que vous avez à m'offrir consistent à me rappeler mon ignorance, ayez au moins la délicatesse de m'indiquer quelques références susceptibles de la combler, si ce n'est pas trop vous demander!

Ceci étant dit, si je m'adresse à ce forum c'est précisément dans l'espoir de trouver une solution à mon problème sans avoir à passer un DEA d'informatique! Il se trouve que j'ai suffisamment de diplômes, et pas suffisamment de temps. Je crois avoir formulé ma réponse de manière assez précise pour attendre une réponse qui ne le soit pas moins.

Je vous serais donc gré de bien vouloir remballer votre mépris, et condescendre à comprendre que certaines évidences ne le sont pas pour tout le monde, et que la question que je vous soumets vise précisément à passer le "cap d'étude et de compréhension indispensable" (dont l'appréciation n'est pas de votre seul ressort)!

Bien à vous,

EL
EL0807 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 15h17   #4
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125
Très cher EL0807 !

Tu es nouveau sur ce forum et vais donc te répondre avec la plus grande gentillesse :

Nul ne te demande de passer un DEA, mais, si tu viens là, c'est que tu t'intéresses à Visual Basic et que tu es prêt à t'y investir.

Il se trouve qu'une fonction, dll ou non, est appelée en observant certaines règles de base, qu'il est important d'assimiler.
L'indication que je t'ai donnée, à savoir :

Citation:
Une fonction retourne une valeur et le type de cette valeur doit donc être défini
.
Etait suffisante pour provoquer un réflexe...
Je précise par ailleurs qu'une fonction doit de surcroît être enregistrée (regsvr32)
En ce qui concerne l'appel d'APIs, tu es invité, après avoir lu les règles de fonctionnement de ce forum, à consulter la rubrique Cours et Tutoriels qui a été rédigée à cet effet. Tu y apprendras l'essentiel (une rubrique très fournie traite des APIs) et te donneras ainsi les moyens d'avancer en connaissance de cause.

Je ne pense pas que ce forum ait pour vocation celle de se substituer purement et simplement, pour le développement, à celui qui souhaite développer. Un minimum de recherches personnelles et de compréhension est indispensable. Et là, il s'agit de la compréhension du mécanisme de déclaration d'une fonction.... et toute chose commence par son commencement.

Comme je te l'ai dit, nous serons certes nombreux à t'épauler lorsque le moment sera venu de pouvoir le faire.

Je t'invite à nouveau à relire les règles de ce forum
http://club.developpez.com/regles/

Si tu pouvais en profiter pour rédiger différemment le titre de ton sujet, toujours en observation des dites règles, tu montrerais aussi l'intérêt que tu portes au bon fonctionnement de ce forum, et celà serait sans aucun doute très apprécié. Je t'en remercie par avance pour l'ensemble et t'assure à nouveau de l'attention que tu recevras dès que tu seras prét.
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 15h44   #5
Responsable Visual Basic
 
Avatar de bbil
 
Inscription : juin 2003
Messages : 11 773
Détails du profil
Informations personnelles :
Âge : 45
Localisation : France, Ariège (Midi Pyrénées)

Informations forums :
Inscription : juin 2003
Messages : 11 773
Points : 16 849
Points : 16 849
Envoyer un message via Skype™ à bbil
Tiens EL0807

ce tutorial devrai t'aider à trouver la maniére d'appeller ta procedure
http://rp.developpez.com/vb/tutoriels/dll/#L6


bbil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 15h51   #6
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125
Il pourrait en effet TRES avantageusement remplacer tout celà par une procédure....
S'il veut à tout prix une dll, je suppose qu'il a ses raisons... ou qu'on le lui a demandé...
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 15h56   #7
Responsable Visual Basic
 
Avatar de bbil
 
Inscription : juin 2003
Messages : 11 773
Détails du profil
Informations personnelles :
Âge : 45
Localisation : France, Ariège (Midi Pyrénées)

Informations forums :
Inscription : juin 2003
Messages : 11 773
Points : 16 849
Points : 16 849
Envoyer un message via Skype™ à bbil
Citation:
Envoyé par jmfmarques
Il pourrait en effet TRES avantageusement remplacer tout celà par une procédure....
S'il veut à tout prix une dll, je suppose qu'il a ses raisons... ou qu'on le lui a demandé...
c'est déjà une procédure ... (dans une dll ... )
bbil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 16h22   #8
Invité régulier
 
Inscription : mars 2006
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 24
Points : 6
Points : 6
Bonjour bbil,
merci pour le conseil. J'avais effectivement repéré ce tutoriel lorsque j'ai commencé à vouloir me lancer dans cette galère. J'ai suivi ses indications à la lettre (crois-je) pour l'exemple du paragraphe 2 (le plus simple!). Sentance : erreur 453.
C'est après cet échec qu'un forumeur m'a conseillé de donner à mon code c++ la forme que je vous ai présenté. ça marche effectivement un peu mieux... sans le __stdcal! d'où l'erreur 49.
Filez-moi une corde...
Bien cordialement,
EL
EL0807 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 18h16   #9
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125
Re bonjour,

En ce qui concerne l'erreur 453, il y est fait référence à la suite de l'exemple 4 du cours
Citation:
Si vous recevez le message d'erreur "Can't find DLL entry point ...", c'est parce que la fonction que vous essayez d'appeler n'a pas été exportée, ou a été exportée sous un nom différent
ton fichier en-tête (en C++ ) est-il complet et ce que tu y a écrit correspond-il bien à l'attente ?
Je ne sais plus si le signe = convient dans le fichier de définitions, entre le nom supposé et le nom donné par le compilateur.
mais je vois que tu as "posté" le même sujet sur le forum C++, ce qui me parait une bonne chose pour ce qui concerne la syntaxe de ta dll, écrite dans ce langage.
http://www.developpez.net/forums/viewtopic.php?t=473418&highlight=

Est-il indispensable de ne pas utiliser directement Msgbox de VB ?
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 18h50   #10
Invité régulier
 
Inscription : mars 2006
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 24
Points : 6
Points : 6
J'ai un fichier Def.h en-tête avec ce code :

Code :
1
2
3
4
 
#include "windows.h"
#define export __declspec (dllexport)
export void __stdcall HelloWorld(void );
Il me semble qu'il y a tout ce qu'il faut pour l'exportation d'une fonction, non?
J'ai ensuite un fichier Fonctions.cpp avec ce code :

Code :
1
2
3
4
5
6
 
#include "Def.h"
void __stdcall HelloWorld(void )
{
    MessageBox(NULL,"Hello !","Message",MB_OK);
}
Les deux fichiers sont dans un projet TestDLL4 que je compile avec Code::Blocks (GNU GCC Compiler) pour créer une dll "Fonction.dll".

Je lis la dll avec Quick View Plus 8.0 : le nom de la fonction est devenu _Z10HelloWorldv@0. Je crée donc un fichier Fonctions.def contenant ces lignes :

LIBRARY Fonctions
DESCRIPTION "Essai de dll"
EXPORTS
HelloWorld _Z10HelloWorldv@0

Tous ces fichiers sont dans un dossier TestDLL6

Dans VBA, j'appelle la dll avec ce code :

Code :
1
2
3
4
5
 
Public Declare Sub HelloWorld Lib "C:\...\TestDLL6\Fonctions.dll" ()
Private Sub test()
HelloWorld
End Sub
résultat : erreur 453.

J'ai pourtant suivi à la lettre les directives du tutoriel (avec adaptation du nom de la fonction, mais mettre le nom indiqué dans le tutoriel ne change rien à l'affaire). J'ai aussi appelé HelloWorld comme un procédure (avec "call"), mais ça ne change rien non plus. Quant à la déclaration de la fonction, il y a le void dans le code c++, et pour le code VB ce n'est pas la première fois que j'en déclare de cette manière sans que ça pose de problème. D'ailleurs, par acquis de conscience, voici un petit code VB que je viens de faire et qui marche parfaitement :

Code :
1
2
3
4
5
6
7
 
Function test()
MsgBox ("toto")
End Function
Private Sub retest()
test
End Sub
Décidément, je ne comprends pas...

Bien cordialement,

EL

PS : A propos de la MsgBox : la boîte de message n'a strictement rien à voir avec mon projet. J'utilise simplement MsgBox pour m'entraîner sur une fonction ultrasimple (et je ne suis visiblement pas le seul, vu les tutoriaux). Pour l'instant, je cherche juste à construire une dll c++ pouvant être appelée dans VBA. C'est la première étape d'un projet plus vaste. Je suis en train de poursuivre une étude scientométrique dans le cadre d'un projet de recherche franco-allemand : il s'agit d'analyser un vaste corpus d'articles scientifiques. Pour ça, j'utilise Access, et j'ai développé un code VBA me permettant de sortir de grosses matrices. Mon problème, c'est qu'une certaine étape du calcul est très lente en VBA. L'idée est donc d'externaliser ce calcul dans une dll C++ pour l'accélérer. La première étape consiste donc à construire une dll c++ pour VBA. La seconde consistera à construite une dll pouvant être connectée à une base Access et pouvant importer des données avec un commande SQL (j'ai déjà repéré des tutoriaux). La suivante à construire le code c++ de traitement des données. Voilà, vous savez tout.
EL0807 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 19h07   #11
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125
Cette partie là ne figurait pas dans ton 1er message, d'où ma question

Code :
1
2
3
#include "windows.h" 
#define export __declspec (dllexport) 
export void __stdcall HelloWorld(void );
le signe = ne figure plus dans le def, ce qui me parait bien (mais je connais mal C++)
J'ai ajouté un edit à mon message précédent en ce qui concerne le sujet que tu as par ailleurs posé sur le forum C++ (et celà me paraît une bonne idée)

Je ne sais pas ce que fais le Void en C++
le msgbox de VB peut inclure plusieurs boutons
je ne vois maintenant aucune erreur dans la façon dont tu appelles ta procédure depuis VB.
Reste donc la partie C++, sa compilation, etc... pour laquelle tu recevras sans doute une réponse sur le forum C++
Bon courage [/quote]

Edit : as-tu essayé d'enregistrer ta dll dans system32 ?
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 19h10   #12
Invité régulier
 
Inscription : mars 2006
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 24
Points : 6
Points : 6
Citation:
Bon courage
Merci, je risque d'en avoir besoin...

Bien cordialement,

EL
EL0807 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 19h11   #13
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125
as-tu essayé d'enregistrer ta dll dans system32 ?
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 19h13   #14
Invité régulier
 
Inscription : mars 2006
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 24
Points : 6
Points : 6
Ehhhhhhhhh oui... dans le répertoire Windows aussi. Pas de changements. Je vais craquer...
EL0807 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 19h14   #15
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125

Il te faut alors attendre la réponde de C++...
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 19h20   #16
Responsable Visual Basic
 
Avatar de bbil
 
Inscription : juin 2003
Messages : 11 773
Détails du profil
Informations personnelles :
Âge : 45
Localisation : France, Ariège (Midi Pyrénées)

Informations forums :
Inscription : juin 2003
Messages : 11 773
Points : 16 849
Points : 16 849
Envoyer un message via Skype™ à bbil
et après voir modifier ton .def... tu as recompilé la dll .. en tenant compte du .def... ( ... de ce que j'en sais le .def ne sert qu'as la compilation ... une fois la dll généré tu n'en as plus besoin... d'ailleurs fais un tour sur ton PC tu ne trouveras pas beaucoup de .def avec tes .dll
bbil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 19h23   #17
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125
Je viens de voir (google) que depuis C++ il y avait 2 catégories de Messagebox dont l'une (API) nécessite un handle :
http://www.francedev.com/cours/cours1.asp
A voir ?
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 20h15   #18
Responsable Visual Basic
 
Avatar de bbil
 
Inscription : juin 2003
Messages : 11 773
Détails du profil
Informations personnelles :
Âge : 45
Localisation : France, Ariège (Midi Pyrénées)

Informations forums :
Inscription : juin 2003
Messages : 11 773
Points : 16 849
Points : 16 849
Envoyer un message via Skype™ à bbil
bon j'ai télécharger codebloc, et créer la dll exemple dont tu parle au début du post ... j'arrive à l'appeller en la déclarant :

par

Code :
Private Declare Sub SomeFunction Lib "d:\tmp\MaDll\Sample.dll" Alias "SomeFunction@4" (ByVal chaine As String)
..
donc c'est un probléme dans le C... sur l'utilisation du .def... peu-être...

youp ... on n'est plus sur le bon forum ... avec le nombre de fois ou j'écrit ... "ce n'est pas le bon forum" je vais me faire appeller ....charle...
bbil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 21h32   #19
Invité régulier
 
Inscription : mars 2006
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 24
Points : 6
Points : 6
bbil, merci beaucoup!
Bon, ce n'est visiblement pas orthodoxe, et il y a en effet probablement un problème dans ma gestion du .def ou dans le code, mais l'essentiel est que ça marche. Et ça marche!
Merci également à tous les autres pour leur patience!
EL0807 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2006, 21h41   #20
Inactif
 
Avatar de jmfmarques
 
Inscription : décembre 2005
Messages : 3 784
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 3 784
Points : 4 125
Points : 4 125
Et... même si pas "catholique"... c'est résolu comment , s'il te plait ?
Celà peut servir à d'autres
jmfmarques est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h19.


 
 
 
 
Partenaires

Hébergement Web