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

C言語系/memos/BCC/01, Win32のEXE,LIB,DLL開発入門(C言語)

C言語系/memos/BCC/01, Win32のEXE,LIB,DLL開発入門(C言語)

C言語系 / memos / BCC / 01, Win32のEXE,LIB,DLL開発入門(C言語)
id: 597 所有者: msakamoto-sf    作成日: 2010-02-24 14:27:24
カテゴリ: C言語 Windows 

C++ は使わずに、C言語とCRT(Cランタイムライブラリ)とWin32APIだけを用いて、コンソール/Windows/スタティックライブラリ/DLL を、コマンドラインからコンパイルして作成する方法のまとめ。UNICODE対応は使わない。

対象:

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

ファイル分割無しの "Hello, World!" イロハ

分割コンパイルを行わない、一番簡単なパターンをまとめる。

コンソール版Hello, World! (BCC32 "-WC"オプション)

特にオプションを指定しない場合は、Win32コンソールアプリケーションとしてコンパイルされ、"main()"関数がエントリポイントになる。

HelloWorld_cui.c:

#include <stdio.h>

int main()
{
	printf("Hello, World!\n");
	return 0;
}

コンパイル&実行:

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

> dir /b HelloWorld_cui.*
HelloWorld_cui.c
helloworld_cui.exe
helloworld_cui.obj
helloworld_cui.tds

> HelloWorld_cui.exe
Hello, World!

TDUMPで確認すると、Subsystemが確かにコンソールアプリケーションになっている:

> tdump -e HelloWorld_cui.exe
(...)
Subsystem                0003 [ Windows character ]
(...)

コンソールアプリであることを明示したい場合は、-WCオプションをつけてコンパイルする。

> bcc32 -WC HelloWorld_cui.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
helloworld_cui.c:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

> helloworld_cui.exe
Hello, World!

Windows版Hello, World! (BCC32 "-W"オプション)

-Wオプションを付けるとWindowsアプリケーションとしてコンパイルされ、"WinMain()"関数がエントリポイントになる。

HelloWorld_gui.c:

#include <windows.h>

int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	MessageBoxA(
		NULL,
		"Hello, Win32 GUI Applications!",
		"Hello, World!",
		MB_OK);

	return 0;
}

コンパイル&実行:

> bcc32 -W HelloWorld_gui.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
helloworld_gui.c:
警告 W8057 helloworld_gui.c 16: パラメータ 'hInstance' は一度も使用されない(関数 WinMain )
警告 W8057 helloworld_gui.c 16: パラメータ 'hPrevInstance' は一度も使用されない(関数 WinMain )
警告 W8057 helloworld_gui.c 16: パラメータ 'lpCmdLine' は一度も使用されない(関数 WinMain )
警告 W8057 helloworld_gui.c 16: パラメータ 'nCmdShow' は一度も使用されない(関数 WinMain )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

> dir /b HelloWorld_gui.*
HelloWorld_gui.c
helloworld_gui.exe
helloworld_gui.obj
helloworld_gui.tds

> HelloWorld_gui.exe
(メッセージボックス表示)

TDUMPで確認すると、Subsystemが確かにWindowsアプリケーションになっている:

> tdump -e HelloWorld_gui.exe
(...)
Subsystem                0002 [ Windows GUI ]
(...)

スタティックライブラリ

※スタティックライブラリを生成するにはTLIBコマンドを使う為、「複数ファイル分割」で紹介。

DLL (BCC32 "-WD"オプション)

-WDオプションを指定するとDLLをターゲットにしてコンパイルする。

※BCC32はデフォルトでC呼び出し規約(cdecl)でコンパイルする。stdcall呼び出し規約でエキスポートする関数には明示的に "__stdcall" を指定する必要がある。(それか"-ps"でデフォルトをstdcallにする。)

libdllfoobarbaz.c:

int __stdcall __declspec(dllexport) foo(int a, int b)
{
	return a + b;
}
int __stdcall __declspec(dllexport) bar(int a, int b)
{
	return a * b;
}
int __stdcall baz(int a, int b)
{
	return a - b;
}

コンパイル:

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

> dir /b libdllfoobarbaz.*
libdllfoobarbaz.c
libdllfoobarbaz.dll
libdllfoobarbaz.obj
libdllfoobarbaz.tds

インポートライブラリまでは作成されない。IMPDEFとIMPLIBコマンドを使ったインポートライブラリの生成については、「複数ファイル分割」で紹介する。

TDUMPコマンドでエクスポートを調べると、foo(), bar()関数がエクスポートされているのを確認出来た:

> tdump -ee libdllfoobarbaz.dll
Turbo Dump  Version 5.0.16.12 Copyright (c) 1988, 2000 Inprise Corporation
                Display of File LIBDLLFOOBARBAZ.DLL

EXPORT ord:0003='___CPPdebugHook'
EXPORT ord:0001='bar'
EXPORT ord:0002='foo'
暗黙的なリンク (implicit link)を使ったアプリ側のビルド

※「複数ファイル分割」で紹介。

明示的なリンク (explicit link)を使ったアプリ側のビルド

usedll_explicit.c:

#include <stdio.h>
#include <windows.h>

typedef int (CALLBACK* lp_foo)(int, int);
typedef int (CALLBACK* lp_bar)(int, int);

int main() {
	HINSTANCE hDll;
	lp_foo foo;
	lp_bar bar;

	hDll = LoadLibrary("libdllfoobar");
	if (NULL == hDll) {
		printf("dll load error.\n");
		return 1;
	}
	foo = (lp_foo)GetProcAddress(hDll, "foo");
	if (!foo) {
		printf("GetProcAddress error(foo).\n");
		FreeLibrary(hDll);
		return 1;
	}
	bar = (lp_foo)GetProcAddress(hDll, "bar");
	if (!bar) {
		printf("GetProcAddress error(bar).\n");
		FreeLibrary(hDll);
		return 1;
	}
	printf("foo(2, 3) = %d\n", foo(2, 3));
	printf("bar(2, 3) = %d\n", bar(2, 3));
	return 0;
}

コンパイル&実行:

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

> usedll_explicit.exe
foo(2, 3) = 5
bar(2, 3) = 6

複数ファイル分割とILINK32の基本

複数ファイルに分割するパターンをまとめる。

ILINK32.EXEで手動でリンクする場合、スタートアップモジュールやライブラリファイルを手動で指定する必要がある。ILINK32.EXEのコマンドラインオプションは以下の形式になっている。

ILINK32 [@respfile][options] startup myobjs, [exe], [mapfile], [libraries], [deffile], [resfile]

"@respfile", "mapfile", "deffile", "resfile"の解説は省略する。

"options"では、/c (シンボルで大文字と小文字を区別)オプションを忘れずに指定すること。
またターゲット指定のオプションを以下に簡単にまとめる。

/aa 32 ビット Windows アプリケーションを構築する
/ad 32 ビット Windows デバイスドライバを構築する
/ap 32 ビット Windows コンソールアプリケーションを構築する
/Tpd Windows の .DLL ファイルをターゲットにする
/Tpe Windows の .EXE ファイルをターゲットにする

"startup", "myobjs"はOBJファイルを列挙する。startupについてはBCCの方でアプリの種類に応じたOBJファイルを用意しているので、それを指定する。主なものを以下に示す。"w"が付くとワイド文字版になる。

c0x32(w).obj 32bitコンソールアプリ用EXEスタートアップモジュール
c0w32(w).obj 32bitWindowsGUIアプリ用EXEスタートアップモジュール
c0d32(w).obj 32bitDLL用スタートアップモジュール

詳細は本記事末尾に載せた参考URL参照。

なお、ファイル名の拡張子部分 ".obj" は省略出来る。

> ilink32 ... c0x32.obj main.obj foo.obj bar.obj ...

と、

> ilink32 ... c0x32 main foo bar ...

は同じ意味になる。

また、カンマ(,)は省略できない点に注意すること。例えばEXEファイル名を指定するには次のようにカンマで区切る。

> ilink32 ... c0x32.obj main.obj foo.obj, myexe.exe, ...

カンマを省略してしまうと、OBJファイルと見なされてしまう。

> ilink32 ... c0x32.obj main.obj foo.obj myexe.exe, ...
→
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Fatal: ファイル MYEXE.EXE が開けません

これは myexe.exe がリンクすべきOBJファイルとして扱われた事が原因。

同様に、マップファイルを省略したい場合もカンマは省略しない。

> ilink32 ... c0x32.obj main.obj foo.obj, myexe.exe, , foo.lib bar.lib, ...

なおターゲットを指定するコマンドラインオプションに応じて、拡張子(".EXE"/".DLL")は省略可能。

最後に、ILINK32で手動リンクする場合はランタイムライブラリを手動で指定する必要がある。本記事で扱う単純なプログラムでは、次の二つを指定すればよい。

CW32.LIB : シングルスレッドのRTL(ランタイムライブラリ)
IMPORT32.LIB : APIのインポートライブラリ

OBJファイルと同様、拡張子の".lib"は省略可能。

> ilink32 ... , cw32.lib import32.lib
=
> ilink32 ... , cw32 import32

マルチスレッドやDirectX, OLE, WININET, WinSock2などを扱う場合は、それぞれ専用のRTLやインポートライブラリが提供されているのでそれを指定する。詳細は本記事末尾に載せた参考URL参照。

リンクはせずにOBJファイルまで生成 (BCC32 "-c"オプション)

DLLまでは、次の foo.c, bar.c を使い回す。

foo.c:

int foo(int a, int b) {
	return a + b;
}

bar.c:

int bar(int a, int b) {
	return a * b;
}

BCC32で-cオプションを指定すると、リンクはせずにOBJファイルのコンパイルまでを行う。

> bcc32 -c foo.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
foo.c:

> bcc32 -c bar.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
bar.c:

OBJファイル名を指定したい場合は、 "-oファイル名" オプションを指定する。

> bcc32 -c -obaz.obj bar.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
bar.c:

> dir /b *.obj
bar.obj
baz.obj
foo.obj

コンソール版 (ILINK32 "/ap", "/Tpe"オプション + c0x32.obj)

/TpeでWindowsのEXEをターゲットとし、"/ap"でWin32コンソールアプリケーションを指定する。
スタートアップモジュールは32bitコンソールのEXE用ということで、c0x32.objを使う。

foobar_cui.c:

#include <stdio.h>

extern int foo(int a, int b);
extern int bar(int a, int b);

int main()
{
	printf("foo(2, 3) = %d\n", foo(2, 3));
	printf("bar(2, 3) = %d\n", bar(2, 3));
	return 0;
}

コンパイル:

> bcc32 -c foobar_cui.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
foobar_cui.c:

リンク&実行:

> ilink32 /c /ap /Tpe c0x32.obj foobar_cui.obj foo.obj bar.obj, foobar_cui.exe, , cw32 import32
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

> foobar_cui.exe
foo(2, 3) = 5
bar(2, 3) = 6

TDUMPで確認すると、Subsystemが確かにコンソールアプリケーションになっている:

> tdump -e foobar_cui.exe
(...)
Subsystem                0003 [ Windows character ]
(...)

参考としてBCC32でリンク&実行させる場合を以下に示す。

> bcc32 -efoobar_cui2.exe -WC foobar_cui.obj foo.obj bar.obj
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

> foobar_cui2.exe
foo(2, 3) = 5
bar(2, 3) = 6

Windows版 (ILINK32 "/aa", "/Tpe"オプション + c0w32.obj)

/TpeでWindowsのEXEをターゲットとし、"/aa"でWin32Windowsアプリケーションを指定する。
スタートアップモジュールは32bitGUIのEXE用ということで、c0w32.objを使う。

foobar_gui.c:

#include <windows.h>
#include <stdio.h>

extern int foo(int a, int b);
extern int bar(int a, int b);

int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	char buf[200];

	sprintf(buf, "foo(2, 3) = %d\n", foo(2, 3));
	MessageBoxA(NULL, buf, "foobar", MB_OK);

	sprintf(buf, "bar(2, 3) = %d\n", bar(2, 3));
	MessageBoxA(NULL, buf, "foobar", MB_OK);

	return 0;
}

コンパイル:

> bcc32 -c foobar_gui.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
foobar_gui.c:
警告 W8057 foobar_gui.c 22: パラメータ 'hInstance' は一度も使用されない(関数 WinMain )
警告 W8057 foobar_gui.c 22: パラメータ 'hPrevInstance' は一度も使用されない(関数 WinMain )
警告 W8057 foobar_gui.c 22: パラメータ 'lpCmdLine' は一度も使用されない(関数 WinMain )
警告 W8057 foobar_gui.c 22: パラメータ 'nCmdShow' は一度も使用されない(関数 WinMain )

リンク&実行:

> ilink32 /c /aa /Tpe c0w32 foobar_gui foo bar, foobar_gui, , cw32 import32
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

> foobar_gui.exe
("foo(2, 3) = 5", "bar(2, 3) = 6" というメッセージボックスが順に表示される)

TDUMPで確認すると、Subsystemが確かにWindowsアプリケーションになっている:

> tdump -e foobar_gui.exe
(...)
Subsystem                0002 [ Windows GUI ]
(...)

参考としてBCC32でリンク&実行させる場合を以下に示す。

> bcc32 -efoobar_gui2.exe -W foobar_gui.obj foo.obj bar.obj
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

> foobar_gui2
("foo(2, 3) = 5", "bar(2, 3) = 6" というメッセージボックスが順に表示される)

スタティックライブラリ(TLIB)

スタティックライブラリを管理するにはTLIB.EXEを使う。
コマンドラインオプションは次のような形になっている。

tlib [@レスポンスファイル] [オプション] ライブラリ名 [演算子] [,リストファイル]

"@レスポンスファイル"については省略。主なオプションは以下の通り。

/a : ファイルをライブラリに追加する。
/d : ファイルをライブラリから削除する。
/u : ライブラリ中のファイルを更新する。
/e : ライブラリからファイルを抽出する。

これらのオプションの代わりに、対象ファイル名の頭に演算子を付けることで操作を指定することもできる。

+foo : foo.objをライブラリに追加する。
-bar : bar.objをライブラリから削除する。
*baz : baz.objをライブラリから抽出する。
-*foobar or *-foobar : foobar.objをライブラリから抽出&ライブラリから削除する。
-+barbaz : barbaz.objを更新する。

".obj" および ".lib" の拡張子は省略出来る。

LIBファイルの内容(リスト)を調べたい時は、", リストファイル"を使う。カンマは省略出来ない。

tlib mylib.lib , mylib_list
→ mylib_list.LST にmylib.libの内容が出力される。

foo.obj, bar.objをスタティックライブラリ"foobar.lib"にまとめ、リストファイルに出力して内容を確認してみる:

> tlib foobar /a foo bar
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation

> tlib foobar , foobar_list
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation

> type foobar_list.LST
Publics by module

bar             size = 11
        _bar

foo             size = 11
        _foo

"+"演算子でfoo.obj, bar.objの順で追加していくサンプル:

> tlib foobar.lib +foo.obj
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation

> tlib foobar.lib , foobar_list.LST
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation

> type foobar_list.LST
Publics by module

foo             size = 11
        _foo

#続いてbar.objを追加してみる:

> tlib foobar.lib +bar.obj
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation

> tlib foobar.lib , foobar_list.LST
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation

> type foobar_list.LST
Publics by module

bar             size = 11
        _bar

foo             size = 11
        _foo

foobar_cui.cをリネームしてfoobar_usestatic.c とし、これをコンパイル&foobar.libとリンクしてみる。

コンパイル:

> bcc32 -c foobar_usestatic.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
foobar_usestatic.c:

リンク&実行:ライブラリファイルにfoobar.libを追加指定。

> ilink32 /c /ap /Tpe c0x32.obj foobar_usestatic.obj, foobar_usestatic.exe, , cw32 import32 foobar
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

> foobar_usestatic.exe
foo(2, 3) = 5
bar(2, 3) = 6

参考としてBCC32でリンク&実行させる場合を以下に示す。

> bcc32 -efoobar_usestatic2.exe -WC foobar_usestatic.obj foobar.lib
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

> foobar_usestatic2.exe
foo(2, 3) = 5
bar(2, 3) = 6

DLLの作成 (ILINK32 "/aa", "/Tpd"オプション + c0d32.obj)

ファイル単体で使ったlibdllfoobarbaz.cを再利用する。BCC32.EXEで一気にDLLを作成するのではなく、ILINK32.EXEに分けてみる。
ただし"__stdcall"は削除し、代わりにコンパイル時に"-ps"オプションを指定しデフォルトをstdcall呼び出し規約にする。
libdllfoobarbaz.c:

int __declspec(dllexport) foo(int a, int b)
{
	return a + b;
}
int __declspec(dllexport) bar(int a, int b)
{
	return a * b;
}
int __stdcall baz(int a, int b)
{
	return a - b;
}

コンパイル:

> bcc32 -c -ps libdllfoobarbaz.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
libdllfoobarbaz.c:

続いて手動でILINK32.EXEを実行してDLLを作成する。

/TpdでWindowsのDLLをターゲットとし、"/aa"でWin32Windowsアプリケーションを指定する。
スタートアップモジュールは32bitのDLL用ということで、c0d32.objを使う。

> ilink32 /c /aa /Tpd c0d32.obj libdllfoobarbaz.obj, libdllfoobarbaz.dll, , cw32 import32
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

インポートライブラリまでは作成されない。
TDUMPコマンドでエクスポートを調べると、foo(), bar()関数がエクスポートされているのを確認出来た:

> tdump -ee libdllfoobarbaz.dll
Turbo Dump  Version 5.0.16.12 Copyright (c) 1988, 2000 Inprise Corporation
                Display of File LIBDLLFOOBARBAZ.DLL

EXPORT ord:0003='___CPPdebugHook'
EXPORT ord:0001='bar'
EXPORT ord:0002='foo'
インポートライブラリの生成(IMPLIB, IMPDEF)

暗黙的なリンクを行うにはインポートライブラリが必要である。BCC32.EXE, ILINK32.EXEでDLLをビルドしてもインポートライブラリは作成されない。IMPLIB.EXEにより手動生成する必要がある。

インポートライブラリというのは、明示的リンク(explicit link)で使ったLoadLibrary()やGetProcAddress()をラップし、DLLが公開している関数名だけでアクセス出来るようにしてくれるライブラリである。
非常に大雑把に描くと以下のようなイメージになる。

クライアント(=アプリケーション)
  foo(2, 3)
  ↓
インポートライブラリ(*.lib)
  h = LoadLibrary("xxxxyyyy");
  f = GetProcAddress(h, "foo");  →→ xxxxyyyy.dll : "foo"関数
  return f(2, 3);

IMPLIB.EXEでは、DLLまたはモジュール定義ファイルを入力として、LIBファイルを出力する。モジュール定義ファイルは手動でインポートライブラリに取り込みたい関数を指定したい場合や、C++の静的メソッドを別名にして取り込みたい場合に使用する。
IMPDEF.EXEを使うと雛形となるモジュール定義ファイルを自動的に生成出来る。
インポートライブラリにとって知りたい情報としてはDLLのファイル名とエキスポートされた関数があればよいため、定義ファイルがあればDLL本体は不要となる。

今回は、上で作成したlibdllfoobarbaz.dllを入力としてみる。

> implib libdllfoobarbaz.lib libdllfoobarbaz.dll

Borland Implib Version 3.0.22 Copyright (c) 1991, 2000 Inprise Corporation

> tlib libdllfoobarbaz.lib , dll.LST
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation

> type dll.LST
Publics by module

___CPPdebugHook size = 0
        ___CPPdebugHook

bar             size = 0
        bar

foo             size = 0
        foo
暗黙的なリンク (implicit link)を使ったアプリ側のビルド

ここまでで材料は揃ったので、暗黙的なリンクを使ってWin32コンソール/Windowsアプリケーションをビルドしてみる。

まずはWin32コンソールアプリケーションから:foobar_usedll_cui.c

#include <stdio.h>

/* "__stdcall" を付けないと、インポートライブラリのシンボルを
   参照出来ず外部シンボル未解決となる */
extern int __stdcall foo(int a, int b);
extern int __stdcall bar(int a, int b);

int main()
{
	printf("foo(2, 3) = %d\n", foo(2, 3));
	printf("bar(2, 3) = %d\n", bar(2, 3));
	return 0;
}

BCC32でコンパイル&実行:(途中メッセージは省略)

> bcc32 -c foobar_usedll_cui.c
> bcc32 -WC foobar_usedll_cui.obj libdllfoobarbaz.lib
> foobar_usedll_cui.exe
foo(2, 3) = 5
bar(2, 3) = 6

ILINK32でリンク&実行::(途中メッセージは省略)

> ilink32 /c /ap /Tpe c0x32.obj foobar_usedll_cui.obj, \
    foobar_usedll_cui2.exe, , cw32 import32 libdllfoobarbaz
> foobar_usedll_cui2.exe
foo(2, 3) = 5
bar(2, 3) = 6

続いてWin32Windowsアプリケーション:foobar_usedll_gui.c

#include <windows.h>
#include <stdio.h>

extern int __stdcall foo(int a, int b);
extern int __stdcall bar(int a, int b);

int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	char buf[200];

	sprintf(buf, "foo(2, 3) = %d\n", foo(2, 3));
	MessageBoxA(NULL, buf, "foobar", MB_OK);

	sprintf(buf, "bar(2, 3) = %d\n", bar(2, 3));
	MessageBoxA(NULL, buf, "foobar", MB_OK);

	return 0;
}

BCC32でコンパイル&実行:(途中メッセージは省略)

> bcc32 -c foobar_usedll_gui.c
> bcc32 -W foobar_usedll_gui.obj libdllfoobarbaz.lib
> foobar_usedll_gui.exe
("foo(2, 3) = 5", "bar(2, 3) = 6" というメッセージボックスが順に表示される)

ILINK32でリンク&実行::(途中メッセージは省略)

> ilink32 /c /aa /Tpe c0w32 foobar_usedll_gui, foobar_usedll_gui2, ,cw32 import32 libdllfoobarbaz
> foobar_usedll_gui2.exe
("foo(2, 3) = 5", "bar(2, 3) = 6" というメッセージボックスが順に表示される)

参考URL

  • Borland C++ Compiler 5.5 - FAQ


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2010-02-24 14:34:13
md5:5bf9984bc754f42480a8fdeccbfd7120
sha1:ff5048175e9122b1f4d83d4d4b41bdd0a88331a9
コメント
コメントを投稿するにはログインして下さい。