none
Programme qui fonctionne mal sur mon deuxième ordinateur. RRS feed

  • Question

  • Bonjour,

    Je programme un petit jeu avec Visual Studio 2010 C++ ( version express ) sur mon portable ( Windows 7 edition 64 bits ) Sur mon portable, tout fonctionne bien. Par contre, une fonction de mon programme ne fonctionne pas sur mon deuxième ordinateur ( Windows 7 edition 32 bits ). Tout les reste fonctionne bien. Cette fonction mélange de façon aléatoire un tableau de n nombres entiers. Voici le code ( inspiré de l'aide pour la fonction rand() ):

    int Melangetableau(int tableau[], int n)  // n nombre d'élément dans le tableau.
    {
     srand( (unsigned) time(NULL));
         int i=0;
         int nombre_tire=0;
         int temp=0; 
     for(i = 0; i < n ; i++ )
     {
         nombre_tire = (double)rand()/(RAND_MAX + 1) * n ; //On tire un nombre aléatoire entre 0 et n-1
         //warning du compilateur C4244: '=' : conversion de 'double' en 'int', perte possible de données
      
     temp = tableau[i];  // On échange les contenus des cases i et nombre_tire
     tableau[i] = tableau[nombre_tire];
     tableau[nombre_tire] = temp;
     }
    return 0;
    }

    Sur mon deuxième ordinateur, un message d'erreur lorsque j'utilise cette fonction :

    Tentative de chargement d'un programme de format incorrect
    ( Exception de HRESULT : 0x8007000B ) 

    "Texte de l'exception "
    System.BadImageFormatException : Tentative de chargement d'un programme de format incorrect. ( Exception de HRESULT : 0x8007000B )
    à _time64(Int64*)
    à ?A0xe3aae30b.time(Int64*_Time)
    à Melangetableau(lnt32*tableau. Int32n)
    à Jeu.Form2.distributionAléatoitreToolStripMenuItem_Click(Object sender, EventArgs e) ........

    C'est a priori la seule fonction de mon programme qui ne tourne pas sur mon deuxième ordinateur .

    (Ps : j'ai copié sur mon deuxième ordinateur les fichiers msvcp100d.dll et msvcr100d.dll )

    Y a - t - il quelque chose de simple à faire, ou mon code ne convient - il pas pour que cette fonction tourne sur mon deuxième ordinateur.

    Merci de votre réponse.

    • Type modifié Aurel Bera jeudi 12 juin 2014 06:00 disc
    • Type modifié Aurel Bera vendredi 13 juin 2014 06:02 quest
    mercredi 4 juin 2014 16:46

Réponses

  • Là c'est juste des log de fusion non ?

    Il n'y a que des assemblies, pas de Dll.

    Dans la fenêtre "Sortie" de VS, il doit avoir les Dll chargées, indiqué chronologiquement.

    Il semble que votre programme soit un mélange un peu confus de code managé et non managé, chose assez courante par nature du C++/CLI.

    Il est préférable de bien distinguer le code managé du code natif dans des classes et des namespaces distincts. Votre remarque 2 est donc un signe encourageant.

    Pour la remarque 1, c'est tout à fait logique, en lançant votre assemblie de l'exe qui a été compilé en MSIL, le code MSIL est "jitté" en code x64 (et non x86) par le runtime .NET de votre portable. La Dll chargée via la fonction _time64 semble donc être aussi du x64.

    Le problème, c'est quand le MSIL est jitté en code x86 sur votre Win7 32bits, _time64 doit charger une mauvaise Dll. en sachant quel Dll est chargé, on pourra voir où est le problème, dans le manifeste, dans le code d'interop, etc...

    Je signale aussi qu'en code natif, il aurait été préférable d'utiliser std::shuffle du C++11 (http://en.cppreference.com/w/cpp/algorithm/random_shuffle).


    Paul Bacelar, Ex - MVP VC++

    • Marqué comme réponse Aurel Bera vendredi 13 juin 2014 06:03
    vendredi 6 juin 2014 01:49
    Modérateur
  • Bonjour,

    J'ai intégré le code de ma fonction MelangeTableau avec le code de la fenêtre où cette fonction est utilisée et déclaré mon tableau sous la forme  static array<Int32^>^ donne = gcnew array<Int32^>{......}; car j'ai besoin de ce tableau pour d'autres fonctions. Le code de ma fonction est :

    int Melangetableau() // n nombre d'éléments du tableau
    {
        int i=0;
        int nombre_tire=0;
        int temp=0;	
    	Thread::Sleep( 1 );
    	Random^ Rand = gcnew Random;
    	for(i = 0; i < 52 ; i++ )
    	{
    	    nombre_tire =  Rand->Next(0,52); //On tire un nombre aléatoire entre 0 et n-1	
    	    temp = *donne[i];  // On échange les contenus des cases i et nombre_tire
    	   *donne[i] = *donne[nombre_tire];
    	   *donne[nombre_tire] = temp;
    	}
       return 0;
    }

    Ce code fonctionne sur mes deux ordinateurs. J' ai même essayé sur un troisième. C'est OK.

    Merci pour les liens très instructifs notés dans vos réponses.


    MJ


    • Modifié tétard jeudi 12 juin 2014 20:29 Problème résolu.
    • Marqué comme réponse Aurel Bera vendredi 13 juin 2014 06:03
    jeudi 12 juin 2014 20:27

Toutes les réponses

  • Bonsoir,

    Le BadImageFormException indique simplement le chargement d'un code 32 bits dans du 64 bits ou bien d'un code 64 bits dans du 32 bits. Quand je parle de code, il s'agit de DLL, assembly, etc.

    Pourriez-vous svp vérifier dans le Gestionnaire de configuration (menu Build/Générer) que vous compiler bien tous vos projets C++ pour du 32 bits ?

    Il y a une option, comme pour C#, pour faire du code Any CPU, plus d'informations ici (http://msdn.microsoft.com/en-us/library/31zwwc39)... Vous risquez toutefois de perdre quelques fonctions C++ cruciales. Pour ces raisons, il vous faut soit compiler deux versions différentes (32 et 64 bits), soit uniquement cibler une version 32 bits qui fonctionnera également sur une machine 64 (Mais en mode émulé grâce à WoW64. On reconnaît ces programmes dans le gestionnaire de tâches des machines 64 bits par un "*32" à la fin du nom des process, ou par le rajout d'une information "(32 bits)")

    Bien cordialement,

    Fabrice JEAN-FRANCOIS

    P.S : Il y a, pour information, une petite astuce sur time qui est désormais par défaut un _time64 (http://msdn.microsoft.com/en-us/library/1f4c8f33.aspx), d'ailleurs vous pouvez voir appraître un Int64 dans votre programme, mais le problème ne doit pas venir de là, c'est compatible sur une machine 32 bits grâce à quelques astuces bas niveau.

    mercredi 4 juin 2014 21:04
  • il y a un problème avec le chargement d'un module dans la seconde machine.

    La sortie du débuggeur indique le chargement des modules. Pouvez-vous indiquer le nom et la nature de la dll en cours de chargement que le débuggeur indique ?


    Paul Bacelar, Ex - MVP VC++


    jeudi 5 juin 2014 12:49
    Modérateur
  • Bonsoir,

    Dans mon gestionnaire de configuration, Configuration de la solution active : Debug , Plateforme de la solution active : Win 32

    Dans l'éditeur de lien, pour le type d'image CLR, je n'ai que 4 options: clr/CLRIMAGETYPE:IJW, clr/CLRIMAGETYPE:PURE, clr/CLRIMAGETYPE:SAFE et Type d'image par défaut ( actuellement selectionnée )

    Modules chargés indiqués à la fin du messsage d'erreur sur mon deuxième ordinateur :

    ************** Assemblys chargés **************
    mscorlib
        Version de l'assembly : 4.0.0.0
        Version Win32 : 4.0.30319.18444 built by: FX451RTMGDR
        CodeBase : file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
    ----------------------------------------
    Jeu
        Version de l'assembly : 1.0.5268.38378
        Version Win32 :
        CodeBase : file:///E:/Michel/Debug/Jeu.exe
    ----------------------------------------
    System.Windows.Forms
        Version de l'assembly : 4.0.0.0
        Version Win32 : 4.0.30319.18408 built by: FX451RTMGREL
        CodeBase : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
    ----------------------------------------
    System.Drawing
        Version de l'assembly : 4.0.0.0
        Version Win32 : 4.0.30319.18408 built by: FX451RTMGREL
        CodeBase : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
    ----------------------------------------
    System
        Version de l'assembly : 4.0.0.0
        Version Win32 : 4.0.30319.18408 built by: FX451RTMGREL
        CodeBase : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
    ----------------------------------------
    mscorlib.resources
        Version de l'assembly : 4.0.0.0
        Version Win32 : 4.0.30319.18408 built by: FX451RTMGREL
        CodeBase : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/mscorlib.resources/v4.0_4.0.0.0_fr_b77a5c561934e089/mscorlib.resources.dll
    ----------------------------------------
    System.Windows.Forms.resources
        Version de l'assembly : 4.0.0.0
        Version Win32 : 4.0.30319.18408 built by: FX451RTMGREL
        CodeBase : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms.resources/v4.0_4.0.0.0_fr_b77a5c561934e089/System.Windows.Forms.resources.dll

    Remarque 1 : mes 2 ordinateurs sont en réseau via ma LiveBox, lorsque depuis mon portable, j'ouvre le programme situé sur mon deuxième ordinateur, il s'exécute normalement sur mon portable.

    Remarque 2: j' ai commencé à modifier mon projet. Ma fonction MelangeTableau et une autre fonction de trie étaient sur un fichiers séparé. Je vais les intégrer dans le code de la fenêtre où elles sont utilisée en utilisant

    un array et System::Random classe.

    Merci de votre aide.


    MJ

    jeudi 5 juin 2014 21:24
  • Là c'est juste des log de fusion non ?

    Il n'y a que des assemblies, pas de Dll.

    Dans la fenêtre "Sortie" de VS, il doit avoir les Dll chargées, indiqué chronologiquement.

    Il semble que votre programme soit un mélange un peu confus de code managé et non managé, chose assez courante par nature du C++/CLI.

    Il est préférable de bien distinguer le code managé du code natif dans des classes et des namespaces distincts. Votre remarque 2 est donc un signe encourageant.

    Pour la remarque 1, c'est tout à fait logique, en lançant votre assemblie de l'exe qui a été compilé en MSIL, le code MSIL est "jitté" en code x64 (et non x86) par le runtime .NET de votre portable. La Dll chargée via la fonction _time64 semble donc être aussi du x64.

    Le problème, c'est quand le MSIL est jitté en code x86 sur votre Win7 32bits, _time64 doit charger une mauvaise Dll. en sachant quel Dll est chargé, on pourra voir où est le problème, dans le manifeste, dans le code d'interop, etc...

    Je signale aussi qu'en code natif, il aurait été préférable d'utiliser std::shuffle du C++11 (http://en.cppreference.com/w/cpp/algorithm/random_shuffle).


    Paul Bacelar, Ex - MVP VC++

    • Marqué comme réponse Aurel Bera vendredi 13 juin 2014 06:03
    vendredi 6 juin 2014 01:49
    Modérateur
  • Bonjour,

    Nous changeons le type de votre question à « Discussion générale ». Si vous avez plus de temps pour réexaminer la question et fournir plus d'informations, n'hésitez pas à modifier le type du thread à « Question ». Si le problème est résolu, s’il vous plaît partagez la solution avec nous afin que la réponse puisse être trouvée et utilisée par d'autres membres de la communauté ayant des questions similaires.

    Merci !

    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    jeudi 12 juin 2014 06:01
  • Bonjour,

    J'ai intégré le code de ma fonction MelangeTableau avec le code de la fenêtre où cette fonction est utilisée et déclaré mon tableau sous la forme  static array<Int32^>^ donne = gcnew array<Int32^>{......}; car j'ai besoin de ce tableau pour d'autres fonctions. Le code de ma fonction est :

    int Melangetableau() // n nombre d'éléments du tableau
    {
        int i=0;
        int nombre_tire=0;
        int temp=0;	
    	Thread::Sleep( 1 );
    	Random^ Rand = gcnew Random;
    	for(i = 0; i < 52 ; i++ )
    	{
    	    nombre_tire =  Rand->Next(0,52); //On tire un nombre aléatoire entre 0 et n-1	
    	    temp = *donne[i];  // On échange les contenus des cases i et nombre_tire
    	   *donne[i] = *donne[nombre_tire];
    	   *donne[nombre_tire] = temp;
    	}
       return 0;
    }

    Ce code fonctionne sur mes deux ordinateurs. J' ai même essayé sur un troisième. C'est OK.

    Merci pour les liens très instructifs notés dans vos réponses.


    MJ


    • Modifié tétard jeudi 12 juin 2014 20:29 Problème résolu.
    • Marqué comme réponse Aurel Bera vendredi 13 juin 2014 06:03
    jeudi 12 juin 2014 20:27