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 :

API windows - .exe qui nécessite des .dll


Sujet :

C++

  1. #1
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut API windows - .exe qui nécessite des .dll
    Bonjour à tous,
    j'ai un petit problème depuis que j'ai réinstallé codeblocks (suite à une actualisation du pc).
    Je ne sais plus exactement quels paramètres j'avais avant, mais je sais que j'arrivais à créer des programmes en mode GUI application sans avoir à rajouter les dll avec le .exe pour pouvoir exécuter ce dernier;
    J'ai un projet .cbp avec le .exe que j'avais compilé avant, et ce .exe pèse 10 ko et s'exécute sans aucune dll.
    Depuis que j'ai réinstallé codeblocks j'ai essayer de recompiler ce projet (donc exactement le même code source) et cela me donne non seulement un .exe qui demande 2 dlls pour s'exécuter, mais qui en plus pèse 16 ko ???
    Je m'en remet donc à vous pour me dire ce que vous en pensez, et ce que je peux faire pour ne pas avoir besoin des .dll pour l'exécution du programme.
    Je vous met le code source de mon programme (au cas où...), qui est permet de mettre en pause le lecteur windows media par un clic sur une petite fenêtre de taille 10*10 toujours en premier plan:
    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
    #include <windows.h>
     
    void ecris(HWND fenetre,int lettre)
    {
        PostMessage(fenetre,WM_KEYDOWN,lettre,0);
        PostMessage(fenetre,WM_KEYUP,lettre,0);
    }
     
    LRESULT WINAPI Proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(Msg){
    	    case WM_LBUTTONDOWN:
    	    {
                //HWND h = GetForegroundWindow();
                HWND handle = FindWindow("WMPlayerApp",0);
                SetForegroundWindow(handle);
                Sleep(1);
                ecris(handle,VK_SPACE);
                //SetForegroundWindow(h);
    	    }
                return 0;
     
    		case WM_CREATE:
    			{
    				ShowWindow(hWnd, SW_SHOW);
    				SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    			}
    			return 0;
    		case WM_PAINT:
    			ValidateRect(hWnd, NULL);
    			return 0;
            case WM_RBUTTONDOWN:
    		case WM_CLOSE:
    		case WM_DESTROY:
    		    {
    		        PostQuitMessage(0);
    		    }
    			return 0;
    	}
    	return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
     
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd)
    {
    	WNDCLASS wndClass = { 0, Proc, 0, 0, hInstance, NULL, LoadCursor(NULL, IDC_ARROW), 0, NULL, "fenetre" };
    	wndClass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
            if(!RegisterClass(&wndClass)) return MessageBox(HWND_DESKTOP, "Cannot register class!", NULL, MB_ICONERROR | MB_OK);
    	HWND hWnd = CreateWindow("fenetre", NULL, WS_POPUP, 0, 0, 10, 10, HWND_DESKTOP, NULL, hInstance, NULL);
            if(!hWnd) return MessageBox(HWND_DESKTOP, "Cannot create window!", NULL, MB_ICONERROR | MB_OK);
    	MSG Msg = { 0 };
    	while(Msg.message != WM_QUIT){
    		if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)){
    			TranslateMessage(&Msg);
    			DispatchMessage(&Msg);
    		}
    		Sleep(30);
    	}
    	return 0;
    }
    Merci d'avance !

  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
    À première vue, je ne vois dans code aucune fonction qui ne fasse pas partie de l'API Windows.
    Quelles sont les deux DLLs en question?
    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
    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
    Quelques remarques par contre:
    1. Si tu SetForegroundWindow() la fenêtre de Windows Media Player, pourquoi utilises-toujours le kludge d'essayer (mal) de simuler une entrée au clavier par message, alors que tu peux utiliser la vraie fonction SendInput() à la place? (ou mieux, piloter WMP par DCOM).
    2. Tu ne devrais pas faire de PostQuitMessage() dans le traitement de WM_CLOSE ou WM_RBUTTONDOWN; réserve ça à WM_DESTROY, traite WM_RBUTTONDOWN par un DestroyWindow(), et WM_RBUTTONDOWN par un PostMessage(WM_CLOSE)...
    3. Quand on précise un HBRUSH dans la WNDCLASS, il faut y ajouter 1 pour avoir la bonne correspondance. COLOR_BACKGROUND correspond en fait à COLOR_SCROLLBAR+1...
    4. Pourquoi faire une attente semi-active dans ta boucle de messages? Vu que tu n'y fais rien d'autre, un GetMessage() ne suffirait-il pas largement? (là en fait, tu forces une attente de 30ms entre chaque message...)
    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.

  4. #4
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    À première vue, je ne vois dans code aucune fonction qui ne fasse pas partie de l'API Windows.
    Quelles sont les deux DLLs en question?
    Merci de cette réponse si rapide !
    Les deux dlls en question sont libgcc_s_dw2-1.dll et libwinpthread-1.dll
    Dites moi si je me trompe, mais un programme n'utilisant que l'api windows ne nécessite pas de dll supplémentaire ?
    Le problème est généralisé à tous les programmes que j'avais fait avant avec l'api windows: quand je les recompile avec ma nouvelle version de codeblocks et mingw, ils pèsent plus lourd (environ 1.5 fois) et nécessite ces deux dll; c'est vraiment étrange (je viens de réinstaller codeblocks et mingw à nouveau, mais ça n'a rien changé).
    Merci beaucoup !

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 077
    Points : 12 129
    Points
    12 129
    Par défaut
    On ne va pas revenir sur le fait que vous vous fourvoyez depuis un certain temps avec ce bricolage avec WMP :
    https://www.developpez.net/forums/d1...-barre-taches/
    @Médinoc en remet une couche sur votre code qui est, concrètement, plus que perfectible.
    Mais dès le démarrage, vous vous prenez la tête pour rien.

    et s'exécute sans aucune dll.
    Ça, c'est du gros pipeau. Il est quasiment impossible de faire un exécutable sans utiliser la moindre dll avec les outils standard.
    "Kernel32.dll" est une dll et c'est le seul moyen officiel d'accéder au système d'exploitation via Win32 (avec quelques autres comme user.dll etc...)
    A la rigueur, vous ne vous êtes pas rendu compte que l'exécutable se servait de dll.
    Utilisez un outil comme dependency walker (http://www.dependencywalker.com/) pour vous rendre compte de l'énormité de vos dires, la prochaine fois.

    On va donc oublier ce "fait" plus que fallacieux et faire dans le simple.
    Il est très probable que vous utilisez des .lib/.a de dll qui ne sont pas ou plus présentes ou accessibles sur votre machines.

    Utilisez dependency walker pour voir les Dll qui manquent. Cela permettra de voir quelles .lib/.a vous utilisez de travers.

    C'était tombé en marche avant, maintenant, c'est la dire réalité, faut correctement configurer son environnement pour qu'il fonction (et qu'il ne soit pas déglingué par une simple "actualisation du pc", preuve s'il en est de la "tombé en marche" par coup de bol).

  6. #6
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Et sinon
    Pourquoi faire une attente semi-active dans ta boucle de messages? Vu que tu n'y fais rien d'autre, un GetMessage() ne suffirait-il pas largement? (là en fait, tu forces une attente de 30ms entre chaque message...)
    Il y a surement mieux mais comme je ne savais pas comment faire, j'ai rajouté ce délai afin que mon programme ne mange pas trop de ram à tourner en boucle.
    Mais s'il y a un moyen comme vous dites de n'agir que lorsqu'un message est détecté par la fenêtre, ça serait encore mieux. Je vais donc regarder du côté de cette fonction GetMessage()...

    Citation Envoyé par bacelar Voir le message
    On ne va pas revenir sur le fait que vous vous fourvoyez depuis un certain temps avec ce bricolage avec WMP :
    https://www.developpez.net/forums/d1...-barre-taches/
    @Médinoc en remet une couche sur votre code qui est, concrètement, plus que perfectible.
    Mais dès le démarrage, vous vous prenez la tête pour rien.


    Ça, c'est du gros pipeau. Il est quasiment impossible de faire un exécutable sans utiliser la moindre dll avec les outils standard.
    "Kernel32.dll" est une dll et c'est le seul moyen officiel d'accéder au système d'exploitation via Win32 (avec quelques autres comme user.dll etc...)
    A la rigueur, vous ne vous êtes pas rendu compte que l'exécutable se servait de dll.
    Utilisez un outil comme dependency walker (http://www.dependencywalker.com/) pour vous rendre compte de l'énormité de vos dires, la prochaine fois.

    On va donc oublier ce "fait" plus que fallacieux et faire dans le simple.
    Il est très probable que vous utilisez des .lib/.a de dll qui ne sont pas ou plus présentes ou accessibles sur votre machines.

    Utilisez dependency walker pour voir les Dll qui manquent. Cela permettra de voir quelles .lib/.a vous utilisez de travers.

    C'était tombé en marche avant, maintenant, c'est la dire réalité, faut correctement configurer son environnement pour qu'il fonction (et qu'il ne soit pas déglingué par une simple "actualisation du pc", preuve s'il en est de la "tombé en marche" par coup de bol).
    Mais pourtant mes anciens programmes fonctionnent toujours (je les ait encore) alors que les nouveaux ne fonctionnent pas.
    Si, comme vous dites, ces programmes utilisaient les dll présentes quelque part sur l'ordinateur, pourquoi les nouveaux programmes ne pourraient-ils pas faire pareil ?
    Sinon, peut importe que ce programme soit à perfectionner ou pas (je sais très bien que je ne maitrise que très peu l'api windows) mais ici je voudrais plutôt savoir pourquoi mes programmes (pas seulement celui-là, je l'ai pris pour l'exemple) compilé avec mon ancien codeblocks marchaient ET MARCHENT ENCORE sur mon pc (et sur les autres pc), alors que les nouveaux ne marchent plus ni sur mon pc ni sur les autres pc sans que je rajoute ces 2 dll dans le dossier où ils sont ???
    Merci de cette réponse

    Mais si vous pensez que codeblocks utilisait des .a ou .lib qu'il incluait dans mes programmes avant afin qu'il n'aient pas besoin de dll, pourquoi est-ce qu'aujourd'hui où codeblocks ne trouverait plus ces .a/.lib les programmes compilés pèseraient plus lourd (si c'était le cas, il devraient peser moins lourd)

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 077
    Points : 12 129
    Points
    12 129
    Par défaut
    Ok, vous ne me croyez pas sur parole, c'est bien, je vais pouvoir me faire mousser.

    Ne prenez pas trop la mouche avec mes sarcasmes déplacés, ce que vous devez comprendre est très très loin d'être évident.

    J'insiste quand même pour dire que vous vous emmerdez à faire un bricolage quand des solutions bien plus élégantes ET plus simples existent.

    Je vais donc répondre à vos interrogations sur "pourquoi ça s'est cassé ? j'ai touché à rien monsieur le professeur".

    Les deux dlls en question sont libgcc_s_dw2-1.dll et libwinpthread-1.dll
    Ok, "libgcc_s_dw2-1.dll", comme le nom l'indique (si on n'est druide Lv36 à AD&D ), c'est une implémentation en Dll de la lib C de GCC, car, sous Windows, la lib C ne fait pas partie de l'OS.
    "libwinpthread-1.dll", idem, c'est une implémentation en dll de la "librairie" pthread.
    C'est le genre de librairie qui existe en 2 versions, en dynamique (avec Dll) et en static (le code de la lib directement dans l'exécutable).
    Il est donc probable que l'ancienne version de C::B était configurée, par défaut?, pour que le linker utilise la version static de ces librairies et que la nouvelle version de C::B demande au linker d'utiliser la version dynamique.
    (Assertion faites avec les informations données dans votre dernier message)

    En tant que développeur, vous ne devriez pas vous reposez sur des réglages par défauts mais les spécifier explicitement, pour ne pas tomber dans le syndrome "c'est tombé en marche, et je savais même pas".

    Regardez dans la documentation de C::B ou du linker que vous utilisez comment configurer les versions des .lib/.a pour quelle correspondent à vos souhaits.

    Dites moi si je me trompe, mais un programme n'utilisant que l'api windows ne nécessite pas de dll supplémentaire ?
    Bin si, cf. mon précédent message.

    Utilisez dependency walker sur les programmes qui "fonctionnent" encore, et vous verrez qu'ils sont toujours dépendants à une flopée de Dll.

    Le problème est généralisé à tous les programmes que j'avais fait avant avec l'api windows: quand je les recompile avec ma nouvelle version de codeblocks et mingw, ils pèsent plus lourd (environ 1.5 fois) et nécessite ces deux dll; c'est vraiment étrange (je viens de réinstaller codeblocks et mingw à nouveau, mais ça n'a rien changé).
    Non, ce n'est pas étrange, c'est que les réglages sont différents.
    C'est peut-être des réglages par défauts différents ou des modifications que vous aviez faites et que vous n'avez pas refaites dans le nouvel environnement.

    Mais pourtant mes anciens programmes fonctionnent toujours (je les ait encore) alors que les nouveaux ne fonctionnent pas.
    Parce que les "anciens" programmes utilisent des Dll qui sont toujours accessibles et que les "nouveaux" programmes utilisent des Dll qui ne sont pas "installées".
    Le code source peut être le même, les outils de génération les mêmes, si la configuration de la chaine de compilation est différentes, l'exécutable généré sera très différent.
    Pour les problématiques d'installation des Dll, c'est fonction de la chaine de compilation et de l'IDE.
    Si vous utilisez des .lib/.a qui sont données avec le compilateur, il y a de très grande chance que les dll associées soient aussi livrées avec le compilateur.
    C'est juste que la manière dont vous lancez l'exécutable ne permet pas de faire en sorte que l'OS trouve ces Dll au bon endroit.
    Compulsez la documentation de votre chaine de compilation de de votre IDE sur le sujet de "l'installation" des Dll.

    Si, comme vous dites, ces programmes utilisaient les dll présentes quelque part sur l'ordinateur, pourquoi les nouveaux programmes ne pourraient-ils pas faire pareil ?
    Les "anciens" programment utilisent des Dll qui sont, d'une manière ou d'une autre, "installées/ accessibles par la manière dont vous lancez l'exécutable" tandis que les nouveaux programmes utilisent, en plus ou à la places, d'autres Dll qui ne sont pas "installées/ accessibles par la manière dont vous lancez l'exécutable".

    "dependency walker" est votre ami.

    je voudrais plutôt savoir pourquoi mes programmes (pas seulement celui-là, je l'ai pris pour l'exemple) compilé avec mon ancien codeblocks marchaient ET MARCHENT ENCORE sur mon pc (et sur les autres pc), alors que les nouveaux ne marchent plus ni sur mon pc ni sur les autres pc sans que je rajoute ces 2 dll dans le dossier où ils sont ???
    La configuration des outils de générations ont changés, rien de bien mystérieux.

    Mais si vous pensez que codeblocks utilisait des .a ou .lib qu'il incluait dans mes programmes avant afin qu'il n'aient pas besoin de dll, pourquoi est-ce qu'aujourd'hui où codeblocks ne trouverait plus ces .a/.lib les programmes compilés pèseraient plus lourd (si c'était le cas, il devraient peser moins lourd)
    Bonne remarque, mais le linker ne met pas le code exécutable de toute la librairie dans l'exécutable, juste le code exécutable effectivement utile à l'exécutable.
    Si vous n'utilisez que peu de fonctions d'une librairie statique, le code ajouté effectivement est très faible.
    Dans la version dynamique, il n'y a pas le code exécutable effectif de la librairie, vue qu'il est dans la Dll, mais il reste toujours le code pour initialiser les structures entre l'exécutable et la Dll ainsi que le code exécutable de "rebond" entre le stub dans l'exécutable et le code dans la Dll.
    Si vous utilisez peu de code de la librairie et qu'il n'est pas complexe, l'exécutable en static peut s’avérer plus concis que l'exécutable dynamique (et il y a beaucoup d'autre facteur qui joue sur la taille effective d'un programme : réglages d'optimisation, utilisation des informations de débuging, etc...).
    Ne vous fiez pas à la taille d'un exécutable, c'est extrêmement trompeur.

  8. #8
    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
    Citation Envoyé par bacelar Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    et s'exécute sans aucune dll.
    Ça, c'est du gros pipeau. Il est quasiment impossible de faire un exécutable sans utiliser la moindre dll avec les outils standard.
    "Kernel32.dll" est une dll et c'est le seul moyen officiel d'accéder au système d'exploitation via Win32 (avec quelques autres comme user.dll etc...)
    A la rigueur, vous ne vous êtes pas rendu compte que l'exécutable se servait de dll.
    Quand on dit "sans aucune DLL" de nos jours, ça veut dire sans aucune DLL extérieure à Windows...
    Ce qui comme tu l'as dit, inclus la libc (du moins par défaut aussi bien sous Visual que sous MinGW) ce qui fait qu'en effet, (pratiquement) aucun programme en C ou C++ ne marche "sans aucune DLL"

    @racine carrée: Finalement pour répondre à ton problème, il y a deux approches:
    1. Déployer les DLLs en question (ou un installeur approprié) avec ton programme
    2. Ne plus dépendre de ces DLL. Ce qui nécessite:
      • Utiliser directement les fonctions de multithreading de l'API Windows (ou de la libc Microsoft, si la version de MinGW implémente elle aussi _beginthreadex()) à la place de pthread: Soit la _beginthreadex() que je viens de mentionner (recommandée par Microsoft pour les programmes en C et C++) soit directement CreateThread().
      • Configurer Code::Blocks pour utiliser la libc de manière statique.
    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.

  9. #9
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Merci beaucoup à bacelar pour sa réponse très détaillée; merci de même à medinoc: je voudrais en effet avoir un programme qui ne nécessite aucune dll supplémentaires à celles inclues de base dans windows, de manière à ce que mon programme marche sur n'importe quel système windows sans avoir à lui joindre de dll. (Sur mon ordi ce n'est pas trop un problème car j'ai rajouté ces 2 dll dans le dossier c/windows/sysWOW64).
    J'imagine que dans la version précédente de codeblocks, les .a/.lib étaient utilisées par défaut, sans même que j'ai eu besoin de rajouter ces librairies dans l'onglet add des options de compilation de mingw. (j'ai pourtant du mal à croire que la taille d'un programme sans les .a soit supérieure à celle des programmes avec les .a, sachant que dans les deux cas j'avais laissé les options de compilation par défaut dans codeblocks).
    Je vais donc essayer de joindre des .a mon programme, si j'y arrive... (sachant que je ne sais pas où trouver ces .a, et quel option du compilateur il faut modifier)
    Merci beaucoup

    Utiliser directement les fonctions de multithreading de l'API Windows (ou de la libc Microsoft, si la version de MinGW implémente elle aussi _beginthreadex()) à la place de pthread: Soit la _beginthreadex() que je viens de mentionner (recommandée par Microsoft pour les programmes en C et C++) soit directement CreateThread().
    J'ai du mal à comprendre tout cela (dans la version précédente ça marchait sans utiliser ces méthodes ???); ne savez vous pas s'il existe un tutoriel expliquant clairement la chose (j'ai toujours du mal avec les explications données sur le site de microsoft )?
    Merci d'avance

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 077
    Points : 12 129
    Points
    12 129
    Par défaut
    Je ne connais pas votre background @racine carrée, mais j'ai l'impression que vous n'avez pas une grosse expérience en système d'exploitation.
    Vos desiderata semble correspondre à une personne totalement novice dans la programmation système, se faisant une vue un peu trop simpliste du domaine.

    je voudrais en effet avoir un programme qui ne nécessite aucune dll supplémentaires à celles inclues de base dans windows, de manière à ce que mon programme marche sur n'importe quel système windows sans avoir à lui joindre de dll.
    C'est pas vraiment comme cela qu'il faut poser le problème.
    Pourquoi ?
    Il n'y a pas un "noyau" inamovible de dll (ni même de primitives systèmes) depuis le premier Windows, en 1982 je crois.
    Windows évolue et évoluera, ne vous en déplaise.
    La démarche qu'il faut avoir, c'est de choisir une version cible (Target Version) de l'OS et faire confiance M$ pour qu'il maintienne le plus longtemps possible et le plus largement possible la compatibilité ascendante des programmes ciblant cette version de l'OS.
    Le manière de choisir l'OS cible est fonction de la chaine de compilation que vous utilisez (préprocesseur, compilateur, éditeur de lien, outils tiers, etc...).

    Même en choisissant un OS cible, cela ne vaut pas dire qu'il n'y aura pas besoin d'installer des Dll.
    Visual Studio, outil phare du développement C++ sous Windows, demande quasi systématiquement l'installation de ce l'on appelle la "Visual Studio Runtime" : un ensemble de dll, d'utilitaires et de réglages de l'OS.
    Cela ne pose, dans les faits, que très peu de problème car ce "Visual Studio Runtime" est livré avec tout MSI généré avec cet outil.
    Idem pour Qt Creator, etc...

    Avec des outils aussi "basic" que C::B et MinGW non configuré, c'est à vous de faire attention à tous ces détails de packaging. MinGW m'a tellement saoulé que j'ai pas trop cherché si, en fin de compte, il existe tous les outils nécessaires pour faire correctement et facilement ce travail de packaging.

    En choisissant l'OS cible, si les outils sont correctement configurés, le processus de génération vous indiquera que vous utilisez des fonctionnalités qui n'existent pas "nativement" sur le système ciblé.
    En faisant attention aux autres options de "compilation" sélectionnées, vous pourrez maitriser si vous utilisez des fonctionnalités "supplémentaires" via l'ajout de code binaire dans l'exécutable (librairies statiques) ou l'ajout d'une dépendance à une dll (librairie dynamique).
    J'ai mis "supplémentaires" entre guillemet car, sous Windows, la C-Runtime ne fait pas parti de l'OS, et est donc une fonctionnalité "supplémentaire". Oui, un simple "malloc" du C tombe dans le dilemme "Dll or not Dll".
    Donc, si vous ne faites pas attention aux options de votre chaine de compilation, vous avez toutes les chances de tomber, par malchance, dans le syndrome "Tombé en marche".
    Malchance très fréquente car les options par défaut sont généralement choisies pour mettre l'utilisateur en "les pieds dans les étriers" (un peu sadiquement ?).
    Le problème avec ce syndrome, c'est qu'il suffit de changer par grand-chose, aussi bien dans l'environnement d'exécution que dans l'environnement de génération, pour que tout parte en cacahouète.
    Pour revenir au "malloc", la version non Dll a, dans beaucoup d'implémentations, pas mal de limitation (pas multi-thread proof, d'autres fonctionnalités plus évoluées absentes) et ne bénéficie pas de tous les avantages innées aux Dll (logique ça). Il est donc très fréquent que l'usage d'outils "évolués" (librairies tierces, frameworks, etc...) requière l'utilisation de la version Dll de la C-Runtime.

    Si vous ne faites rien au niveau de la configuration de votre chaine logicielle, vous êtes à la merci du moindre changement des réglages par défaut de vos outils, un pantin.

    En réfléchissant sur la nature des Dll qui vous pose problème et aux limitations habituelles des C-Runtime statiques, il est bien possible que l'usage l'implémentation des pthread que vous utilisez requière une version dynamique de la C-Runtime. Dans un contexte où on laisse la chaine de compilation faire ce qu'elle veut, de tels réglages peuvent être imposés par les .h utilisés, directement ou indirectement. Comme vous n'indiquez rien à la chaine de compilation, elle ne contredira pas les réglages imposés par les .h. Si vous spécifiez ces réglages, la chaine pourra vérifier qu'ils correspondent à ceux imposés par les .h et vous prévenir du problème s'ils contredisent vos choix.

    Ici, si vous voulez une implémentation statique de la C-Runtime, indiquez-la à votre chaine de compilation.
    Soit les .h sont souples et gèrent cette "injonction", soit ils ne le sont pas et la chaine de compilation vous indiquera où ça coince.

    Faire une C-Runtime multi-thread proof en statique, c'est un gouffre à performance, alors, que cela ne soit pas ou plus le cas du réglage par défaut, ne me surprend pas.

    Donc, arrêtez d'être un pantin et indiquez clairement vos choix.

    (Sur mon ordi ce n'est pas trop un problème car j'ai rajouté ces 2 dll dans le dossier c/windows/sysWOW64).

    "c/windows/sysWOW64)" n'est pas un dépotoir à Dll !!!!
    Vous avez au vérifié que c'était des Dll 32bits et pas 64 avant de les fourrer dans l'autoclave à virus de votre machine ???

    NON, vous devez "gérer" le déploiement des Dll utilisées => usage de packageur pour générer des MSI.
    Sur des machines de développement, donc pas super durci en terme de sécurité, mettre les Dll dans le répertoire contenant l'exécutable ou dans le répertoire de travail du processus lors de l'exécution sont des solutions qui fonctionnent très souvent.

    Si c'est pour donner à vos copains proches, qui ne s’offusqueront pas de se faire "engueuler" par l'anti-virus ni de réduire à néant leur dur labeur de durcissement sécuritaire de leur machine, cette approche de dll dans le répertoire de l'exécutable ou du working directory peut aussi être viable.

    Mais bon, un MSI, c'est pas la mort à faire.

    J'imagine que dans la version précédente de codeblocks, les .a/.lib étaient utilisées par défaut, sans même que j'ai eu besoin de rajouter ces librairies dans l'onglet add des options de compilation de mingw.
    Que cela soit du statique ou du dynamique, des .a/.lib sont utilisés. Quand c'est du statique, ils contiennent le code binaire, quand c'est du dynamique, ils contiennent le code binaire de rebond vers le code binaire dans la Dll.
    C'est donc pas la présence ou pas de ces .a/.lib mais lesquels sont utilisés qu'il faut vérifier.

    (j'ai pourtant du mal à croire que la taille d'un programme sans les .a soit supérieure à celle des programmes avec les .a, sachant que dans les deux cas j'avais laissé les options de compilation par défaut dans codeblocks).
    Les 2 options utilisent du code binaires, le code de rebond n'a pas une taille nulle.
    De plus, le code de rebond ne peut pas être optimisé (ou très très difficilement) contrairement aux codes binaire récupérés dans des librairies statiques (inlining, etc...).
    Vous ne connaissez pas assez bien tout le bordel derrière la compilation pour raisonner aveuglement simplement sur la taille d'une image résultat de la compilation. Exactement comme deviner la taille du résultat de la décompression d'un zip, juste avec la taille du zip.
    Il y a des milliers de réglages qui peuvent influencer la taille de l'image et il suffit d'un seul changement dans ces réglages par défaut pour expliquer ce changement de taille.

    Je vais donc essayer de joindre des .a mon programme, si j'y arrive...
    Je ne suis pas sûr que cela soit vraiment le plus simple.

    J'ai du mal à comprendre tout cela (dans la version précédente ça marchait sans utiliser ces méthodes ???); ne savez vous pas s'il existe un tutoriel expliquant clairement la chose (j'ai toujours du mal avec les explications données sur le site de microsoft )?
    Je vous re-conseille chaudement d'utiliser "dependency walker" pour avoir une vue exacte du problème et donc mieux comprendre ce qui est expliqué sur le Net.

    J'espère qu'avec nos conseils, les discutions trouvées à l'arrache via Google n'est plus du chinois pour vous :
    https://stackoverflow.com/questions/...dll-is-missing

  11. #11
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Merci beaucoup de prendre tant de temps pour m'expliquer ces notions; il est en effet difficile de se débarrasser de ces préjugés de débutant !
    Je vai tester dependency walker, et essayer de me familiariser un peu plus avec les options du compilateur...
    Merci encore !

    @medinoc:
    voilà les améliorations que j'ai pu faire grâce à vos conseils:
    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
    #include <windows.h>
     
    void ecris(HWND fenetre,int lettre)
    {
        PostMessage(fenetre,WM_KEYDOWN,lettre,0);
        PostMessage(fenetre,WM_KEYUP,lettre,0);
    }
     
    LRESULT WINAPI Proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(Msg){
    	    case WM_LBUTTONDOWN:
    	    {
                HWND handle = FindWindow("WMPlayerApp",0);
                ecris(handle,VK_SPACE);
    	    }
                return 0;
    		case WM_CREATE:
    			{
    				ShowWindow(hWnd, SW_SHOW);
    				SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    			}
    			return 0;
    		case WM_PAINT:
    			ValidateRect(hWnd, NULL);
    			return 0;
            case WM_RBUTTONDOWN:
    		case WM_CLOSE:
    		    {
    		        DestroyWindow(hWnd);
    		    }
    		    return 0;
    		case WM_DESTROY:
    		    {
    		        PostQuitMessage(0);
    		    }
    			return 0;
    	}
    	return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
     
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd)
    {
    	WNDCLASS wndClass = { 0, Proc, 0, 0, hInstance, NULL, LoadCursor(NULL, IDC_ARROW), 0, NULL, "fenetre" };
    	wndClass.hbrBackground = (HBRUSH) 1;
            if(!RegisterClass(&wndClass)) return MessageBox(HWND_DESKTOP, "Cannot register class!", NULL, MB_ICONERROR | MB_OK);
    	HWND hWnd = CreateWindow("fenetre", NULL, WS_POPUP, 0, 0, 10, 10, HWND_DESKTOP, NULL, hInstance, NULL);
            if(!hWnd) return MessageBox(HWND_DESKTOP, "Cannot create window!", NULL, MB_ICONERROR | MB_OK);
    	MSG msg = { 0 };
    	while(GetMessage(&msg,hWnd,0,0)!=-1)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    	return 0;
    }
    Merci !

  12. #12
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Bonjour à tous,
    je suis passé à mingw64 (j'étais à mingw32) et j'ai laissé exactement les mêmes options de compilation que pour mingw32, sauf bien sur le toulchain-executables;
    et bien je n'ai plus besoin des deux dlls !
    Je ne sais pas d'où ça vient (en tout cas ça ne peut pas venir des options de compilation, donc ça vient peut-être du compilateur lui-même), mais tant mieux puisque ça marche !!!

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 077
    Points : 12 129
    Points
    12 129
    Par défaut
    Je ne vois pas ce qui te permet d'affirmer que ce n'est pas des options de compilation, à moins d'avoir la trace de la commande console de génération des .obj ET de l'édition de lien.
    La majorité des options de compilation ne sont pas spécifiées, par défaut, dans un IDE aussi rudimentaire que Code::Blocks.
    Vous êtes toujours en plein syndrome "c'est tombé en marche", et vous vous faites balader par différentes versions des compilateurs, de l'IDE, et de la couleur du vent.

    mais tant mieux puisque ça marche !!!
    Vous êtes au moins lucide que cela ne va pas durer. Une mise à jours d'un outil quelconque et c'est la Bérézina.

    Voici un lien vers un article qui développe la problématique Mingw64 (GCC en général) et les dll :
    https://stackoverflow.com/questions/...with-mingw-w64

  14. #14
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Effectivement, je disais cela sur le ton de la plaisanterie...
    Par contre je ne savais pas que le compilateur pouvait avoir des options par défaut qui ne soient pas dans codeblocks; dans ce cas, comment peut-on savoir quelle sont ces options et comment les modifier pour comprendre comment elles marchent ?

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 077
    Points : 12 129
    Points
    12 129
    Par défaut
    Je crois que même Code::Blocks logue la ligne de commande qu'il transmet aux outils de la chaine logicielle.

  16. #16
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Oui, mais j'ai la même ligne de commande qu'avant, à part bien sur g++.exe qui devient x86_64-w64-mingw32-g++.exe
    A savoir:
    x86_64-w64-mingw32-g++.exe -Wall -O2 -fexpensive-optimizations -O3 -c "C:\Users\...\1-codebloc projects\prog\main.cpp" -o obj\Release\main.o
    x86_64-w64-mingw32-g++.exe -o bin\Release\prog.exe obj\Release\main.o -s -s -lgdi32 -luser32 -lkernel32 -lcomctl32 -mwindows

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 077
    Points : 12 129
    Points
    12 129
    Par défaut
    g++ dispose de plus de milles options différentes, vos ligne de commande utilise un énorme paquet de valeurs par défaut.
    Si vous ne voulez pas de lib C en dll, il faudrait que vous l'indiquiez EXPLICITEMENT, via les flags du linker.
    https://stackoverflow.com/questions/...dll-is-missing

  18. #18
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Donc si j'ai bien compris, en 64 bits le compilateur mingw (pour la version actuelle) utilise par défaut lib C en librairie statique (incluse dans le .exe) au lieu d'une dll, alors que mingw32 (pour la version actuelle, mais pas pour la version que j'avais avant d'actualiser mon pc) utilise par défaut lib C en dll ? Et donc, si on ne veut pas avoir de mauvaise surprise il faut le spécifier explicitement et non le laisser faire comme ça par défaut ?
    Pourtant j'avais fait le test avec mingw32, j'avais ajouté les deux options suivantes: -static-libgcc et -static-libstdc++, mais cela n'avait rien changé (je les avais peut-être pas mis au bon endroit?)
    Merci beaucoup !

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 077
    Points : 12 129
    Points
    12 129
    Par défaut
    Donc si j'ai bien compris, en 64 bits le compilateur mingw ...
    C'est un peu plus compliqué que cela.
    Il n'y a pas UNE configuration par défaut, car des options spécifiées dans les lignes de commandes peuvent faire changer les choix par défaut, pour qu'ils soient plus adaptés à ces options.
    C'est fait pour nous simplifier la vie, en principe.
    Si on dit (via les options en ligne de commandes) ce que l'on veut, la chaine de compilation va faire les choix qu'elle croit les plus pertinents.
    Si vous n'indiquez rien, elle choisit ce qu'elle évalue le plus pertinents.
    Et dans un environnement Windows, l'utilisation de Dll est clairement ce qu'il y a de moins casse-gueule.

    Si vous spécifiez des options contradictoires, au moins la chaine de compilation vous enverra bouler avec un message clair sur les options incompatibles.

    Et donc, si on ne veut pas avoir de mauvaise surprise il faut le spécifier explicitement et non le laisser faire comme ça par défaut ?
    Oui

    (je les avais peut-être pas mis au bon endroit?)
    Très probablement, où il y a avait des messages d'erreurs ou des Warning vous indiquant un problème.

  20. #20
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Merci beaucoup,
    je vais retester avec mingw32 et les deux options à mettre pour le linker (-static-libgcc et -static-libstdc++) et je verrai bien si cette fois ça marche !
    Merci encore!

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

Discussions similaires

  1. [DLL+EXE] Comment Inclure des DLL dans un EXE
    Par alavoler dans le forum C#
    Réponses: 7
    Dernier message: 20/03/2010, 23h25
  2. Réponses: 13
    Dernier message: 01/06/2007, 14h55
  3. Un anti-spam qui nécessite des droits d'admin !?
    Par marcogringo dans le forum Windows Serveur
    Réponses: 7
    Dernier message: 25/04/2007, 20h54
  4. Réponses: 2
    Dernier message: 04/05/2006, 19h53
  5. Réponses: 4
    Dernier message: 26/01/2006, 10h48

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