質問
ネイティブWindowsアプリケーションを開発および展開するときは、バイナリを実行する前にランタイムをインストールするか、ライブラリをバイナリに静的にリンクする必要があることがよくあります。たとえば、Visual Studio 2008で「Win32コンソール」プロジェクトを構築した後、新鮮なWindows 7画像でプログラムを実行しようとすると、次のようになります。
アプリケーションは、並んで構成が正しくないため、開始できませんでした。詳細については、アプリケーションイベントログを参照するか、コマンドラインsxstrace.exeツールを使用してください。
このような問題が育ちました その他の投稿 Stackoverflowで。
アプリケーションをどのように開発しますか しないでください ターゲットOSにまだ載っていないランタイムが必要です(つまり、再配布可能なパッケージやプライベート/共有並べ替えのアセンブリをインストールする必要はありません)? MSVC [MPR] 90.DLLの使用を避け、 Windows System32*。{dll、sys}でWindows APIを使用するにはどうすればよいですか?
私はデモスセンから出てくるコードの線に沿って考えていますが、それは頻繁に利用できません。
解決
他の人は、CRTを静的にリンクすることに関してすでに対応しています。また、同時に小さなバイナリが必要な場合は、最善の策が完全にForego CRTであり、Win32 API機能のみを可能な限り使用します。あなたはまだいくつかのCRTコードを取得します、特にスタートアップに関連しています(つまり、呼び出すものは main
)そしてシャットダウン(atexit
処理など)が、それ以外の場合は、リンカーは使用しないCRT関数をリンクしません。
使用することにより、CRTを完全にリンクすることを避けることができます /Zl
コンパイラスイッチ。この意味は main
ただし、機能しなくなります - 定義する必要があります WinMain
(名前は問題ではありませんが、署名は一致する必要があり、そうでなければなりません __stdcall
)、そしてあなたはあなたの名前を指定する必要があります WinMain
- リンカーを介したエントリポイントとしての関数のように /entry:
スイッチ。これにより、〜30kbのCRTコードが節約されます(空のcppでテストされます main
).
後者のルートに行く場合は、Compiler Intrinsicsの問題にも対処する必要がある場合があります。 CRTによって名目上定義されている(およびヘッダーで宣言されている)が、コンパイラによって特別に扱われる機能がいくつかあります。 memset
, strlen
, 、および機能のかなりの部分 <math.h>
;完全なリストを見つけることができます ここ. 。 CRTがないため、これらの機能が必要な場合、またはそれを回避できますが、パフォーマンスが向上したために本質的なものを好む( memset
, 、たとえば)、あなたはそれらを自分で宣言し、使用する必要があります #pragma intrinsic
. 。例えば:
// 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;
}
上記は次のようにコンパイルできます。
cl /c /Zl foo.cpp
link /entry:main foo.obj
他のヒント
CRTを介して静的にリンクします /MT
スイッチ(および同様にMFCを使用している場合)。
静的リンクは、DLLでできることを多少制限しますが、単純な実行可能ファイルでは魅力のように機能します。 (そして、DLLを出荷する場合は、とにかくいつでもプライベートアセンブリを出荷できます。)
静的CRTを使用します。これは、MSVC*.dllに依存することはありません。 CRTはプログラムに直接リンクされています。これは依存関係を作成するものではありませんが、実行可能ファイルのサイズが増加します。
さまざまなCRTオプションの詳細 ここ.
ランタイムを静的にリンクします。 MS VisualC ++にはそのためにオプション /MTがあります(デフォルトは /MD)
これを行う方法の1つは、Visual Studioを使用しないで、代わりにコマンドラインSDKツールに依存することだと思います。 (代わりに、あなたが望むことを行うように設定する方法を把握することができますが、それは難しいようです。)例:
cl /c app.cpp
link app.obj ws2_32.lib