#include <windows.h> BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { MessageBox(NULL, "Hello World!", "nopdll", MB_OK); return TRUE; } |
#include <windows.h> int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { MessageBox(NULL, "Hello World!", "nopdll", MB_OK); return 1; } |
コンパイラ | DLLサイズ |
Visual C++6.0 SP4 | 40,960 Byte |
C++Builder5 | 48,128 Byte |
# makefile cc = cl link = link # cflags:コンパイラオプション cflags = /nologo /O1 # lflags:リンカオプション lflags = /nologo /DLL /NODEFAULTLIB /ENTRY:"DllMain" /opt:nowin98 /merge:.data=.text /merge:.rdata=.text /section:.text,erw # dll:DLLのファイル名 dll = nop_vc.dll # objs:ソースの分だけ追加 objs = nop_vc.obj # libs:必要なライブラリ libs = user32.lib # --------------------------------------------------- # ソースファイルの拡張子が".c"の場合 .c.obj: $(cc) $(cflags) -c $< # 使いまわせるように".cpp"も入れとく .cpp.obj: $(cc) $(cflags) -c $< $(dll) : $(objs) $(link) $** $(libs) $(lflags) /out:$@ |
nmake /F minidll.mak |
Visual C++のリンカには/EntryというexeやDLLのエントリポイントを指定するオプションがあり、ランタイムライブラリのスタートアップルーチンをいれないようにすることができる。ということらしい。(ただし、これはBorland C++5.2向けの記事なのでC++Builderのリンカilink32とは違うかもしれない)
Borlandのリンカにはこのようなオプションが無いのだが、同じことを実現する方法が2つある。エントリポイントをアセンブラで書く。または、tlink32はランタイムライブラリ抜きでリンクできるので、エントリポイントのアドレスをあとで設定しなおす。
bcc32 -O1 -c nopbcb.c ilink32.exe /Tpd nopbcb.obj , nopbcb.dll, , import32.lib |
#include <windows.h> void __declspec(dllexport) __stdcall nop(void); int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { MessageBox(NULL, "Hello World!", "nopdll", MB_OK); return 1; } void __stdcall nop(void) { return; } |
# makefile cc = bcc32 link = ilink32 # cflags:コンパイラオプション cflags = -O1 -w-par # dll:プラグインのファイル名 dll = nopbcb.dll # objs:ソースの分だけ追加 objs = nopbcb.obj # --------------------------------------------------- # ソースファイルの拡張子が".c"の場合 .c.obj: $(cc) $(cflags) -c $< # 使いまわせるように".cpp"も入れとく .cpp.obj: $(cc) $(cflags) -c $< $(dll): $(objs) $(link) /Tpd /Gn /x $** , $@, , import32.lib |
make -f minidll.mak |
コンパイラ | 使用前 | 使用後 |
Visual C++6.0 SP4 | 40,960 Byte | 1,536 Byte |
C++Builder5 | 48,128 Byte | 4,608 Byte |
.386p _TEXT SEGMENT PUBLIC DWORD USE32 'CODE' PUBLIC EntryPoint EntryPoint proc near mov eax, 1 ret 12 EntryPoint endp _TEXT ENDS END EntryPoint |
tasm32 dllmain.asm ilink32 /Tpd dllmain.obj , nopbcb.dll, , import32.lib |
0000 : 4D 5A 60 00 01 00 00 00 04 00 00 00 FF FF 00 00 MZ`............. 0010 : B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@....... 0020 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0030 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0040 : 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 0D 0A ........!..L.!.. 0050 : 68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 2E 0D 0A 24 hello, world...$これは「hello, world.」と表示するMS-DOSプログラムのdumpです。
コンパイラ | プラグインサイズ |
Visual C++6.0 SP3 | 3,072 Byte |
Visual C++6.0 SP4 | 3,584 Byte |
Visual C++6.0 SP4 (小さいスタブプログラムを使用) | 3,072 Byte |
C++Builder5 | 5,632 Byte |