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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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.

PS : j'ai également posté ce message sur le forum VB, la question concernant aussi ce langage. J'espère que ce doublon ne pose pas de problème.

Addendum : on vient de m'indiquer une astuce en VBA qui permet de faire fonctionner le code (déclarer la fonction dans l'appel VB en mettant en alias le nom de la fonction transformée par le __stdcall). J'ai donc indiqué que le problème était résolu du côté du VB. Je le laisse ici, car il reste probablement un problème du côté de la gestion du .def ou du code c++. Si quelqu'un à une idée...