#navi_header|C言語系| Borland C++ Compiler での、コンパイラ/リンカオプションやライブラリなどの早見表、および [[597]] では取りあげなかったミニTipsなど。 #more|| 対象: > bcc32 Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland (...) > ilink32 Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland (...) #outline|| ---- * 各種早見表 以下のFAQ掲載のスタートアップモジュール/インポートライブラリ、および [[597]] で取りあげたいくつかのコマンドラインオプションをまとめておく。 - Borland C++ Compiler 5.5 - FAQ -- http://edn.embarcadero.com/jp/article/33545 ** BCC32.EXEでのターゲット/マルチスレッド/UNICODE/ダイナミックRTL指定 ターゲットを指定するには、次の3つのオプションのいずれかを指定する。 -W : GUIアプリケーション -WC : コンソールアプリケーション -WD : DLL 以下のオプションは、他のオプションと組み合わせて使用出来る。 -WM : マルチスレッド -WU : UNICODE対応 -WR : ダイナミックRTLを使用 ** ILINK32.EXEで手動リンクするスタートアップモジュールと特殊処理オブジェクト ※W付はワイド文字版 | C0X32(W).OBJ | 32ビットコンソールモード用EXEスタートアップモジュール | | C0W32(W).OBJ | GUI .EXE用スタートアップモジュール | | C0D32(W).OBJ | DLLスタートアップモジュール | | C0D32X.OBJ | DLLスタートアップモジュール(例外処理なし) | | FILEINFO.OBJ | オープンしているファイルハンドル情報を子プロセスへ渡すときに使う | | GP.OBJ | 例外処理発生時にレジスタダンプを印刷する | | WILDARGS.OBJ | ワイルドカード引数を評価 | ** 提供されているライブラリ | CW32.LIB | シングルスレッドのRTL | | CW32I.LIB | シングルスレッドのRTL(CC3250.DLL)用 ImportLIB | | CW32MT.LIB | マルチスレッドのRTL | | CW32MTI.LIB | マルチスレッドのRTL(CC3250MT.DLL)用 ImportLib | | DXEXTRA.LIB | DirectX用スタティックLib | | IMPORT32.LIB | APIのインポートライブラリ | | INET.LIB | MS Internet DLL用ImportLib | | NOEH32.LIB | 例外処理を除外するためのライブラリ | | OLE2W32.LIB | 32ビットOLE 2.0API用Import Lib | | OLEAUT32.LIB | 32ビットOLE 2.0API用Import Lib | | UUID.LIB | Direct3D、DirectDraw、シェルエクステンションなどのためのGUIDライブラリ | | WININET.LIB | WININET.LIB用ImportLib | | WS2_32.LIB | 32ビットWinSock 2.0用ImportLib | ・コンソールアプリ: スタートアップモジュール : C0X32.OBJ ライブラリ: CW32.LIB + IMPORT32.LIB ・GUIアプリ: スタートアップモジュール : C0W32.OBJ ライブラリ: CW32.LIB + IMPORT32.LIB ・ランタイムライブラリをDLLとしてリンクする場合は、CW32.LIBではなくCW32I.LIBをリンクする。 CW32I.LIB をリンク → CC3250.DLL が必要(BINディレクトリ中に存在) CW32MTI.LIB をリンク → CC3250MT.DLL が必要(同上) ※いずれも32bitGUIアプリ対応 ・マルチスレッド用のライブラリ(CW32MT.LIB/CW32MTI.LIB)はBCC32.EXEでの -WM オプション指定時に使う。 ・NOEH32.LIBを指定して例外処理を扱わないようにすることで、BCCで作成するアプリケーションの実行ファイルのサイズを節約することが可能。ただしC++の入出力クラスなど例外処理が必要な場合は無効。 ** ILINK32.EXEでのターゲット指定オプション [[597]] の複数ファイル分割の項から再掲: ILINK32 [@respfile][options] startup myobjs, [exe], [mapfile], [libraries], [deffile], [resfile] "options"では、/c (シンボルで大文字と小文字を区別)オプションを忘れずに指定すること。 またターゲット指定のオプションを以下に簡単にまとめる。 | /aa | 32 ビット Windows アプリケーションを構築する | | /ad | 32 ビット Windows デバイスドライバを構築する | | /ap | 32 ビット Windows コンソールアプリケーションを構築する | | /Tpd | Windows の .DLL ファイルをターゲットにする | | /Tpe | Windows の .EXE ファイルをターゲットにする | * COFFとOMF, COFF2OMF Visual C++ 2008 のC++コンパイラが生成するインポートライブラリは ''COFF (Common Object File Format)'' というファイル形式になっている。一方Borland C++ Compilerが生成するOBJ, LIBファイルは ''(Relocatable) OMF (Object Module Format)'' というファイル形式になっている。 - Common Object File Format -- http://en.wikipedia.org/wiki/COFF - (Relocatable) Object Module Format -- http://en.wikipedia.org/wiki/Relocatable_Object_Module_Format この違いが問題となってくるのは、Visual C++ で生成したインポートライブラリをBorland C++ Compilerでリンクする場合である。 Visual C++ → xxyy.dll (PE: Porable Executable ファイル) xxyy.lib (COFF) ↓ BCC32/ILINK32 client.obj (OMF) → このままではCOFF形式のLIBをOMF形式のOBJとリンク出来ない! ここで登場するのが Borland C++ Compiler に含まれている COFF2OMF.EXE である。 まずCOFF形式のインポートライブラリをリンクしようとすると、エラーとなってしまうことを確認する。 > dir foobar_usedll_cui.c libdllfoobarbaz.dll ... VC++2008で生成したDLL libdllfoobarbaz.lib ... 同上のインポートライブラリ(COFF形式) > bcc32 -c foobar_usedll_cui.c > bcc32 -WC foobar_usedll_cui.obj libdllfoobarbaz.lib Error: 'C:\IN_VITRO\C\BCCTEST03\LIBDLLFOOBARBAZ.LIB' contains invalid OMF record, type 0x21 (possibly COFF) (foobar_usedll_cui.cおよびlibdllfoobarbaz.dllのソースは省略) COFF2OMFを使って、OMF形式のインポートライブラリ "libdllfoobarbaz_omf.lib" に変換してリンク&実行: > COFF2OMF libdllfoobarbaz.lib libdllfoobarbaz_omf.lib > bcc32 -WC foobar_usedll_cui.obj libdllfoobarbaz_omf.lib > foobar_usedll_cui.exe foo(2, 3) = 5 bar(2, 3) = 6 DLL側とアプリ側とで呼び出し規約を一致させる必要がある点に注意すること。これがずれてしまうと、スタックのクリーンアップがずれてしまい異常終了の原因になる。 呼び出し規約に応じてシンボル名の修飾が入るが、COFF2OMFでは"-lib"オプションで修飾名の調整を行える。 "-lib:ms" : MS C++ の名前の変形(name mangling)のあるエントリを許可(デフォルト: no) "-lib:st" : MS stdcall の変形にエリアスを使うかわりに名前を標準化する "-lib:ca" : MS cdecl エリアス使用を行わない(デフォルトはエリアシングする) 呼び出し規約が一致しなくとも、"-lib"オプションを調整することで「無理矢理」リンクに成功させることも出来るが、当然、異常終了の原因となる。 呼び出し規約の不一致による異常終了は、アセンブラのレベルでデバッグをしないと発見が難しい。重ね重ね注意が必要である。 * アセンブラコードの出力(BCC32, "-S"オプション) アセンブラコードを出力するには、"-S"オプションを使う。 bar.c: #pre||> int bar(int a, int b) { return a * b; } ||< アセンブラファイルは拡張子が".asm"で出力される。 > bcc32 -S bar.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland bar.c: bar.asm: #pre||> .386p (...) _bar proc near ?live1@0: ; ; int bar(int a, int b) { ; push ebp mov ebp,esp ; ; return a * b; ; @1: mov eax,dword ptr [ebp+8] imul dword ptr [ebp+12] ; ; } ; @3: @2: pop ebp ret _bar endp _TEXT ends public _bar ?debug D "bar.c" 15447 27147 end ||< これをコンパイルするにはTASM32が必要らしい。 例えばOllyDbgのLoaddllはアセンブラで書かれており、TASM32でコンパイルされる。((それよりも、リソースファイルに実行ファイルイメージを埋め込んでいる方が気になって仕方ない。使う時は一時ファイルとかに吐きだして実行してるのかな?)) - Loaddll -- http://www.ollydbg.de/Asmcode.htm * TDUMPの使い方 イロハ EXE or DLLファイルのヘッダー情報をダンプ tdump -e xxxx.exe tdump -e xxxx.dll エクスポートの一覧をダンプ tdump -ee xxxx.exe tdump -ee xxxx.dll インポート一覧をダンプ tdump -em xxxx.exe インポートしたモジュール一覧をダンプ tdump -em. xxxx.exe COFF形式のOBJ, LIBファイルをダンプ tdump -C xxxx.obj tdump -C xxxx.lib #navi_footer|C言語系|