Question

Lors du développement et du déploiement d'applications Windows natives, j'ai souvent besoin d'installer un runtime avant de pouvoir exécuter mon binaire ou de lier statiquement la bibliothèque avec mon binaire. Par exemple, après avoir construit un projet "Console Win32" avec Visual Studio 2008, tentant d'exécuter le programme sur une nouvelle image Windows 7 Résultats:

L'application n'a pas réussi à démarrer car sa configuration côte à côte est incorrecte. Veuillez consulter le journal des événements de l'application ou utiliser l'outil de ligne de commande sxstrace.exe pour plus de détails.

Des problèmes comme celui-ci ont été soulevés Autres messages sur stackOverflow.

Comment développer des applications qui ne le faites pas exiger des temps d'exécution qui ne sont pas déjà sur le système d'exploitation cible (c'est-à-dire ne pas nécessiter d'installation de packages redistribuables ou d'assemblages côte à côte)? Comment éviter d'utiliser MSVC [MPR] 90.dll et utilisez simplement l'API Windows dans Windows System32 *. {DLL, SYS}?

Je pense dans le sens du code qui sort du Demoscene, mais ce n'est souvent pas mis à disposition.

Était-ce utile?

La solution

D'autres ont déjà répondu en ce qui concerne la liaison de CRT statiquement. Si vous voulez également un petit binaire en même temps, votre meilleur pari est de renoncer entièrement à CRT et d'utiliser uniquement les fonctions API Win32 autant que possible. Vous obtiendrez toujours du code CRT, notamment lié au démarrage (c'est-à-dire ce qui appelle main) et l'arrêt (atexit Manipulation, etc.), mais sinon le linker ne liera pas les fonctions CRT que vous n'utilisez pas.

Vous pouvez éviter de lier complètement le CRT en utilisant /Zl Commutateur de compilateur. Cela signifie que main ne fonctionnera plus, cependant - vous devrez définir WinMain (Le nom n'a pas d'importance, mais la signature doit correspondre, et elle doit être __stdcall), et vous devrez spécifier le nom de votre WinMain- Fonction comme un point d'entrée via l'éditeur de liens /entry: changer. Cela vous fera économiser ~ 30 Ko de code CRT (testé sur un .cpp avec un vide main).

Si vous empruntez ce dernier itinéraire, vous devrez peut-être également faire face à la question de l'intrinssique du compilateur. Il existe certaines fonctions qui sont définies nominalement par le CRT (et déclarées dans ses en-têtes), mais qui sont traitées spécialement par le compilateur, afin qu'il insère des instructions d'assemblage optimisées au point de l'appel lorsque cela est possible - les exemples sont memset, strlen, et une bonne partie de fonctions dans <math.h>; Une liste complète peut être trouvée ici. Puisque vous n'avez pas de CRT, si vous avez besoin de ces fonctions, ou pourriez l'éviter mais préférez l'intrinsèque en raison de performances améliorées (difficile à faire mieux que memset, par exemple), alors vous devez les déclarer vous-même et utiliser #pragma intrinsic. Par exemple:

// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h> 

extern "C"
{
    int abs(int);
    void* memset(void*, int, size_t); 
}

#pragma intrinsic(abs, memset)

int __stdcall main(void*, void*, char*, int)
{
    char tmp[10];
    memset(tmp, abs(-123), 10);
    return 0;
}

Ce qui précède peut être compilé avec:

cl /c /Zl foo.cpp
link /entry:main foo.obj

Autres conseils

Lier le CRT statiquement via le /MT Changer (et également MFC, si vous l'utilisez).

La liaison statique limite quelque peu ce que vous pouvez faire avec les DLL, mais pour les exécutables simples, il fonctionne comme un charme. (Et si vous expédiez des DLL, vous pouvez toujours expédier des assemblées privées de toute façon.)

Utilisez le CRT statique. Cela ne crée pas de dépendance à MSVC * .dll. Le CRT est lié directement à votre programme. Cela ne crée pas de dépendances, mais augmente la taille de votre exécutable.

Plus d'informations sur différentes options CRT ici.

Lier statiquement le runtime. MS Visual C ++ a une option / MT pour cela (par défaut est / MD)

Je pense qu'une façon de le faire est de ne pas utiliser Visual Studio et de compter à la place sur les outils SDK de la ligne de commande. (Vous pouvez alternativement à déterminer comment configurer vs pour faire ce que vous voulez, mais cela semble plus difficile.) Par exemple:

cl /c app.cpp
link app.obj ws2_32.lib
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top