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

C++ Discussion :

[C++] problème en utilisant un DLL: "the value of ESP was not properly saved"


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Points : 17
    Points
    17
    Par défaut [C++] problème en utilisant un DLL: "the value of ESP was not properly saved"
    saluts,

    compilateur: Visual C++ 6.0.
    nous sommes rélativement nouveaux à la programmation en C++. nous essayons d'utiliser un ActiveX DLL créé dans Visual Basic 6.0.
    pour utiliser le DLL, nous utilisons #import, et autres fonctions pour créer l'instance et appeller les fonctions du DLL, comme décrit dans un tutoriel.
    l'initialisation du DLL (COM) fonctionne; le problème surgit quand nous essayons d'appeller une fonction du DLL. le code du programme est dessous. le projet du DLL en VB est appellé mbr et il contient une classe appellée mbrl. quand la fonction t->speak(...) est appellé, l'erreur suivante se passe:

    "File: i386/chkesp.c
    Line: 42

    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."
    que voit dire:
    "Le valeur d'ESP n'a pas été sauvé correctement à travers un appel de fonction. C'est habituellement un résultat d'appeler une fonction déclarée avec une convention d'appel avec un pointeur de fonction déclaré avec une convention d'appel différente."

    ici est le code (un petit programme):
    Code C++ : 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
    #import "C:\WINDOWS\system32\mbr.dll"
    #include "iostream"
    #include <windows.h>
    using namespace std;
    using namespace mbr;
     
    int main(int argc, char* argv[])
    {
     
         HRESULT hresult;
         CLSID clsid;
         _mbrl *t;
    			_bstr_t		bstrValue("k 100 100\n");
    			_bstr_t		dbe("ar1");
    			_bstr_t		oute("OUT.WAV");
    			_bstr_t		bstrR("");
    			long		freqe;
    			long		dure;
    			long		vole;
    			long		pite;
    			long		returne;
    			freqe = 1;
    			dure = 1;
    			vole = 1;
    			pite = 1;
         ::CoInitialize(NULL);
          hresult=CLSIDFromProgID(OLESTR("mbr.mbrl"), &clsid);
          hresult= CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
                                       __uuidof(_mbrl),(LPVOID*) &t);
          if(hresult == S_OK)
          {
     
    		 returne = t->speak(bstrValue, freqe, dure, vole, pite, dbe, oute); // <- L'ERREUR SE PASSE ICI
             t->Release();
    		 ::CoUninitialize;
           }
         return 0;
    }

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pour un appel via COM, c'est vraiment bizarre: Les appels via COM sont standardisé, et dans le cas présent, le code pour les appels de fonction est généré automatiquement...

    Ce genre d'erreur, on l'a plutôt quand on utilise mal un pointeur de fonction...

    Peux-tu poster le .tlh généré par #import ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre à l'essai
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    saluts,

    merci pour la réponse.
    voici le TLH.
    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
    69
    70
     
    #pragma once
    #pragma pack(push, 8)
     
    #include <comdef.h>
     
    namespace mbr {
     
    //
    // Forward references and typedefs
    //
     
    struct __declspec(uuid("67922a88-3442-47d7-a24b-fcd8269217da"))
    /* dual interface */ _mbrl;
    struct /* coclass */ mbrl;
     
    //
    // Smart pointer typedef declarations
    //
     
    _COM_SMARTPTR_TYPEDEF(_mbrl, __uuidof(_mbrl));
     
    //
    // Type library items
    //
     
    struct __declspec(uuid("67922a88-3442-47d7-a24b-fcd8269217da"))
    _mbrl : IDispatch
    {
        //
        // Wrapper methods for error-handling
        //
     
        long speak (
            _bstr_t textus,
            long freq,
            long dur,
            long vol,
            long pit,
            _bstr_t db,
            _bstr_t out );
     
        //
        // Raw methods provided by interface
        //
     
        virtual HRESULT __stdcall raw_speak (
            BSTR textus,
            long freq,
            long dur,
            long vol,
            long pit,
            BSTR db,
            BSTR out,
            long * _arg8 ) = 0;
    };
     
    struct __declspec(uuid("25eada00-b527-4a7c-b50d-cfb06a76beda"))
    mbrl;
        // [ default ] interface _mbrl
     
    //
    // Wrapper method implementations
    //
     
    #include "c:\myprojects\mbr\debug\mbr.tli"
     
    } // namespace mbr
     
    #pragma pack(pop)

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Eh bien, c'est de plus en plus bizarre, car la fonction est bien déclarée en __stdcall...

    Es-tu sûr que les paramètres sont les bons, et du bon type ?
    Puis-je voir la déclaration VB de la fonction?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre à l'essai
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    merci pour la réponse.
    oui, c'est bizarre, parce que, auparavant, l'erreur que s'est passé était "Access Violation", mais - ce doit être à cause d'une modification que nous avons fait mais nous ne nous souvenons pas - l'erreur est, maintenant, celui-ci.
    en tout cas, voici la déclaration VB:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Public Function speak(ByVal textus As String, ByVal freq As Long, ByVal dur As Long, ByVal vol As Long, ByVal pit As Long, ByVal db As String, 
    ByVal out As String) As Long

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Que se passe-t-il si tu essaies d'appeler directement raw_speak() plutôt que le wrapper généré par Visual ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre à l'essai
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    merci pour la réponse.
    quand nous appelons raw_speak():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t->raw_speak(bstrValue, freqe, dure, vole, pite, dbe, oute, &returne);
    la même erreur se passe.
    est-ce que vous avez quelque idée? est-ce que nous pouvons vous donner quelque information additionelle que peut aider?
    merci d'avance.

  8. #8
    Membre à l'essai
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    nous avons découverte une chose:
    les fonctions du DLL fonctionnent, à l'exception du speak().
    le problème est que le notre DLL, mbr.dll, communique avec un autre DLL, que n'est pas créé par nous (dans le projet VB du mbr, il y a un module avec des déclarations aux fonctions de l'autre DLL, que sont utilisés par notre DLL).
    quand nous effaçons les fonctions à l'intérieur du speak qu'appellent l'autre DLL, cette erreur ne se passe pas (le problème est que les fonctions de l'autre DLL sont importantes).
    donc, nous avons découvert ce que cause le problème, mais non pourquoi.
    peut-être ces fonctions ne sont pas déclarées __stdcall?
    déclarations (nous ne savons pas s'il aidera):
    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
    Declare Function MBR_Play Lib "mbrplay.dll" Alias "_MBR_Play@16" (ByVal lpszText As String, ByVal dwFlags As Long, ByVal lpszOutFile As String, ByVal dwCallback As Long) As Long
    Declare Function MBR_Stop Lib "mbrplay.dll" Alias "_MBR_Stop@0" () As Long
    Declare Function MBR_WaitForEnd Lib "mbrplay.dll" Alias "_MBR_WaitForEnd@0" () As Long
    Declare Function MBR_SetPitchRatio Lib "mbrplay.dll" Alias "_MBR_SetPitchRatio@4" (ByVal fPitch As Single) As Long
    Declare Function MBR_SetDurationRatio Lib "mbrplay.dll" Alias "_MBR_SetDurationRatio@4" (ByVal fDuration As Single) As Long
    Declare Function MBR_SetVoiceFreq Lib "mbrplay.dll" Alias "_MBR_SetVoiceFreq@4" (ByVal lFreq As Long) As Long
    Declare Function MBR_SetVolumeRatio Lib "mbrplay.dll" Alias "_MBR_SetVolumeRatio@4" (ByVal fVol As Single) As Long
    Declare Function MBR_SetNoError Lib "mbrplay.dll" Alias "_MBR_SetNoError@4" (ByVal bSet As Long) As Long
    Declare Function MBR_GetPitchRatio Lib "mbrplay.dll" Alias "_MBR_GetPitchRatio@0" () As Single
    Declare Function MBR_GetDurationRatio Lib "mbrplay.dll" Alias "_MBR_GetDurationRatio@0" () As Single
    Declare Function MBR_GetVoiceFreq Lib "mbrplay.dll" Alias "_MBR_GetVoiceFreq@0" () As Long
    Declare Function MBR_GetVolumeRatio Lib "mbrplay.dll" Alias "_MBR_GetVolumeRatio@0" () As Single
    Declare Function MBR_GetNoError Lib "mbrplay.dll" Alias "_MBR_GetNoError@0" () As Long
    Declare Function MBR_SetDatabase Lib "mbrplay.dll" Alias "_MBR_SetDatabase@4" (ByVal lpszID As String) As Long
    Declare Function MBR_SetDatabaseEx Lib "mbrplay.dll" Alias "_MBR_SetDatabaseEx@12" (ByVal lpszID As String, ByVal lpszReplace As String, ByVal lpszClone As String) As Long
    Declare Function MBR_GetDatabase Lib "mbrplay.dll" Alias "_MBR_GetDatabase@8" (ByVal lpID As String, ByVal dwSize As Long) As Long
    Declare Function MBR_IsPlaying Lib "mbrplay.dll" Alias "_MBR_IsPlaying@0" () As Long
    Declare Function MBR_LastError Lib "mbrplay.dll" Alias "_MBR_LastError@8" (ByVal lpszError As String, ByVal dwSize As Long) As Long
    Declare Function MBR_GetVersion Lib "mbrplay.dll" Alias "_MBR_GetVersion@8" (ByVal lpVersion As String, ByVal dwSize As Long) As Long
    Declare Function MBR_GetDefaultFreq Lib "mbrplay.dll" Alias "_MBR_GetDefaultFreq@0" () As Long
    Declare Function MBR_GetDatabaseInfo Lib "mbrplay.dll" Alias "_MBR_GetDatabaseInfo@12" (ByVal idx As Long, ByVal lpMsg As String, ByVal dwSize As Long) As Long
    Declare Function MBR_GetDatabaseAllInfo Lib "mbrplay.dll" Alias "_MBR_GetDatabaseAllInfo@8" (ByVal lpMsg As String, ByVal dwSize As Long) As Long
    Declare Function MBR_RegEnumDatabase Lib "mbrplay.dll" Alias "_MBR_RegEnumDatabase@8" (ByVal lpszData As String, ByVal dwSize As Long) As Long
    Declare Function MBR_RegEnumDatabaseCallback Lib "mbrplay.dll" Alias "_MBR_RegEnumDatabaseCallback@8" (lpszID As Any, ByVal dwUser As Long) As Long
    Declare Function MBR_RegGetDatabaseLabel Lib "mbrplay.dll" Alias "_MBR_RegGetDatabaseLabel@12" (ByVal lpszID As String, ByVal lpLabel As String, ByVal dwSize As Long) As Long
    Declare Function MBR_RegGetDatabasePath Lib "mbrplay.dll" Alias "_MBR_RegGetDatabasePath@12" (ByVal lpszID As String, ByVal lpPath As String, ByVal dwSize As Long) As Long
    Declare Function MBR_RegGetDatabaseCount Lib "mbrplay.dll" Alias "_MBR_RegGetDatabaseCount@0" () As Long
    Declare Function MBR_RegGetDefaultDatabase Lib "mbrplay.dll" Alias "_MBR_RegGetDefaultDatabase@8" (ByVal lpID As String, ByVal dwSize As Long) As Long
    Declare Function MBR_RegSetDefaultDatabase Lib "mbrplay.dll" Alias "_MBR_RegSetDefaultDatabase@4" (ByVal lpszID As String) As Long
    Declare Function MBR_RegisterDatabase Lib "mbrplay.dll" Alias "_MBR_RegisterDatabase@24" (ByVal dbId As String, ByVal dbPath As String, ByVal dbLabel As String, ByVal isDef As Long, ByVal lpBuffer As String, ByVal dwSize As Long) As Long
    Declare Function MBR_UnregisterDatabase Lib "mbrplay.dll" Alias "_MBR_UnregisterDatabase@4" (ByVal dbId As String) As Long
    Declare Function MBR_UnregisterAll Lib "mbrplay.dll" Alias "_MBR_UnregisterAll@0" () As Long
    Declare Function MBR_DatabaseExist Lib "mbrplay.dll" Alias "_MBR_DatabaseExist@4" (ByVal lpszID As String) As Long
    Declare Function MBR_RegIdxGetDatabaseId Lib "mbrplay.dll" Alias "_MBR_RegIdxGetDatabaseId@12" (ByVal nIdx As Long, ByVal lpszID As String, ByVal dwSize As Long) As Long
    Declare Function MBR_RegIdxGetDatabasePath Lib "mbrplay.dll" Alias "_MBR_RegIdxGetDatabasePath@12" (ByVal nIdx As Long, ByVal pszPath As String, ByVal dwSize As Long) As Long
    Declare Function MBR_RegIdxGetDatabaseLabel Lib "mbrplay.dll" Alias "_MBR_RegIdxGetDatabaseLabel@12" (ByVal nIdx As Long, ByVal lpszLabel As String, ByVal dwSize As Long) As Long
    Declare Function MBR_RegIdxGetDatabaseIndex Lib "mbrplay.dll" Alias "_MBR_RegIdxGetDatabaseIndex@12" (ByVal lpszID As String) As Long
    Declare Function MBR_RegIdxGetDefaultDatabase Lib "mbrplay.dll" Alias "_MBR_RegIdxGetDefaultDatabase@0" () As Long
    Declare Function MBR_StartControlPanel Lib "mbrplay.dll" Alias "_MBR_StartControlPanel@4" (Hwnd As Long) As Long
    Declare Function MBR_SetCallbackMsgBase Lib "mbrlay.dll" Alias "_MBR_SetCallbackMsgBase@4" (dwBase As Long) As Long
    Declare Function MBR_MBRUnload Lib "mbrplay.dll" Alias "_MBR_MBRUnload@0" ()
    merci d'avance.

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    C'est donc l'intérieur de la fonction speak() qui plante et non son appel?
    Ça m'ôte une épine du pied, car je ne voyais vraiment pas ce qui pouvait faire planter l'appel...

    Cette ligne (4e avant la fin) est anormale :
    Code VB : Sélectionner tout - Visualiser dans une fenêtre à part
    Declare Function MBR_RegIdxGetDatabaseIndex Lib "mbrplay.dll" Alias "_MBR_RegIdxGetDatabaseIndex@12" (ByVal lpszID As String) As Long
    La fonction devrait accepter trois paramètres 32 bits et non pas un seul.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre à l'essai
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    merci pour la réponse.
    oui, nous aurions dû remarquer ce plus tôt...
    réellement, nous ne comprennons pas ce que vous avez dit au sujet de cette fonction.
    mais les seules fonctions externes (de l'autre DLL) utilisées par speak() sont:
    MBR_SetDatabase
    MBR_SetPitchRatio
    MBR_SetVoiceFreq
    MBR_SetDurationRatio
    MBR_SetVolumeRatio
    MBR_Play
    MBR_LastError
    MBR_MBRUnload
    mais nous pensons que c'est étrange, parce que la partie de C++ seulement appelle les fonctions du mbr.DLL - c'est le mbr.DLL, créé dans VB, qu'appelle les fonctions de l'autre DLL - , donc l'appel de C++ à mbr.dll ne devrait avoir problème avec les fonctions de l'intérieur du speak(), parce que c'est la partie du VB, n'est-ce pas?
    merci d'avance.

  11. #11
    Membre à l'essai
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    saluts,

    nous avons résolu le problème.
    réellement, nous n'avons pas résulu "le problème", mais nous avons simplement connecté avec l'autre DLL directement du C++, au lieu de faire un DLL que connecte avec l'autre DLL. donc, nous avons simplement évité le problème.
    bien que nous encore ne savons pas pourquoi cette erreur s'est passé...

    merci pour la patience.

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

Discussions similaires

  1. [JDBC]Problème de configuration: "Failed to load the sqljdbc_auth.dll"
    Par adrien.nicolet dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 26/01/2014, 11h14
  2. Réponses: 1
    Dernier message: 21/12/2012, 22h26
  3. The expression prefix 'SPUrl' was not recognized - WSS
    Par lthomas dans le forum SharePoint
    Réponses: 1
    Dernier message: 14/04/2008, 15h58
  4. Problème d'utilisation de Dll faite maison. . .
    Par _SamSoft_ dans le forum Windows
    Réponses: 27
    Dernier message: 20/02/2007, 13h55
  5. Réponses: 1
    Dernier message: 12/01/2007, 21h40

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