home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

C言語系/memos/BCC/02, 早見表とミニTips

C言語系/memos/BCC/02, 早見表とミニTips

C言語系 / memos / BCC / 02, 早見表とミニTips
id: 600 所有者: msakamoto-sf    作成日: 2010-02-24 23:39:13
カテゴリ: C言語 Windows 

Borland C++ Compiler での、コンパイラ/リンカオプションやライブラリなどの早見表、および C言語系/memos/BCC/01, Win32のEXE,LIB,DLL開発入門(C言語) では取りあげなかったミニTipsなど。

対象:

> bcc32
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
(...)
> ilink32
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
(...)

各種早見表

以下のFAQ掲載のスタートアップモジュール/インポートライブラリ、および C言語系/memos/BCC/01, Win32のEXE,LIB,DLL開発入門(C言語) で取りあげたいくつかのコマンドラインオプションをまとめておく。

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でのターゲット指定オプション

C言語系/memos/BCC/01, Win32のEXE,LIB,DLL開発入門(C言語) の複数ファイル分割の項から再掲:

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)というファイル形式になっている。

この違いが問題となってくるのは、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:

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:

	.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でコンパイルされる。*1

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

*1: それよりも、リソースファイルに実行ファイルイメージを埋め込んでいる方が気になって仕方ない。使う時は一時ファイルとかに吐きだして実行してるのかな?

プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2010-02-25 09:03:54
md5:6a8c9ac0a594b703b824191db04760d1
sha1:ab08e149471b2a15e178d3f6774abef12082aa7c
コメント
コメントを投稿するにはログインして下さい。