#navi_header|C言語系| ''"WINAPI", "CALLBACK", "APIENTRY"'' はヘッダーファイルで定義された呼び出し規約で、実際にどの呼び出し規約("__stdcall", "__cdecl", "__pascal", ...)になるかは OS/コンパイラによって異なってくるので、使用する場合は注意が必要。 ''ただし、2010年現在の Win32 APIプラットフォームにおいては基本的にどれも "__stdcall" と考えて良い。'' VC++2008, Borland C++ Compiler共に、この3つは"__stdcall"にdefineされている。 #more|| ---- #outline|| ---- * サンプルコード(winapis.c) WINAPI, CALLBACK, APIENTRY はWin32API用なので、使うにはWindows用のヘッダーファイルをincludeする必要がある。今回は "windows.h" をincludeした。 #code|c|> #include #include int WINAPI foo1(int a, int b, int c, int d, int e) { return a + b + c + d + e; } int CALLBACK foo2(int a, int b, int c, int d, int e) { return a + b + c + d + e; } int APIENTRY foo3(int a, int b, int c, int d, int e) { return a + b + c + d + e; } int main(int argc, char *argv[]) { printf("foo1() = %d\n", foo1(1, 2, 3, 4, 5)); printf("foo2() = %d\n", foo2(6, 7, 8, 9, 0)); printf("foo3() = %d\n", foo3(10, 20, 30, 40, 50)); return 0; } ||< * VC++2008 Express Edtion プリプロセス結果およびアセンブラ出力から、"__stdcall" にdefineされている事が分かる。 コンパイル&リンク&実行 #pre||> > cl /FAs /TC /Od /nologo /c winapis.c > link /SUBSYSTEM:CONSOLE /NOLOGO /OUT:winapis.exe winapis.obj > winapis.exe foo1() = 15 foo2() = 30 foo3() = 150 ||< プリプロセス結果を生成: > cl /P /TC /Od /nologo /c winapis.c プリプロセス結果: #code|c|> #line 3 "winapis.c" int __stdcall foo1(int a, int b, int c, int d, int e) { return a + b + c + d + e; } int __stdcall foo2(int a, int b, int c, int d, int e) { return a + b + c + d + e; } int __stdcall foo3(int a, int b, int c, int d, int e) { return a + b + c + d + e; } int main(int argc, char *argv[]) { printf("foo1() = %d\n", foo1(1, 2, 3, 4, 5)); printf("foo2() = %d\n", foo2(6, 7, 8, 9, 0)); printf("foo3() = %d\n", foo3(10, 20, 30, 40, 50)); return 0; } ||< ** アセンブラ出力(winapis.asm) #pre||> ; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 TITLE C:\in_vitro\c\cc_vc\winapis.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES _DATA SEGMENT $SG78612 DB 'foo1() = %d', 0aH, 00H ORG $+3 $SG78613 DB 'foo2() = %d', 0aH, 00H ORG $+3 $SG78614 DB 'foo3() = %d', 0aH, 00H _DATA ENDS PUBLIC _foo1@20 ; Function compile flags: /Odtp ; File c:\in_vitro\c\cc_vc\winapis.c _TEXT SEGMENT _a$ = 8 ; size = 4 _b$ = 12 ; size = 4 _c$ = 16 ; size = 4 _d$ = 20 ; size = 4 _e$ = 24 ; size = 4 _foo1@20 PROC ; 6 : { return a + b + c + d + e; } push ebp mov ebp, esp mov eax, DWORD PTR _a$[ebp] add eax, DWORD PTR _b$[ebp] add eax, DWORD PTR _c$[ebp] add eax, DWORD PTR _d$[ebp] add eax, DWORD PTR _e$[ebp] pop ebp ret 20 ; 00000014H _foo1@20 ENDP _TEXT ENDS PUBLIC _foo2@20 ; Function compile flags: /Odtp _TEXT SEGMENT _a$ = 8 ; size = 4 _b$ = 12 ; size = 4 _c$ = 16 ; size = 4 _d$ = 20 ; size = 4 _e$ = 24 ; size = 4 _foo2@20 PROC ; 10 : { return a + b + c + d + e; } push ebp mov ebp, esp mov eax, DWORD PTR _a$[ebp] add eax, DWORD PTR _b$[ebp] add eax, DWORD PTR _c$[ebp] add eax, DWORD PTR _d$[ebp] add eax, DWORD PTR _e$[ebp] pop ebp ret 20 ; 00000014H _foo2@20 ENDP _TEXT ENDS PUBLIC _foo3@20 ; Function compile flags: /Odtp _TEXT SEGMENT _a$ = 8 ; size = 4 _b$ = 12 ; size = 4 _c$ = 16 ; size = 4 _d$ = 20 ; size = 4 _e$ = 24 ; size = 4 _foo3@20 PROC ; 14 : { return a + b + c + d + e; } push ebp mov ebp, esp mov eax, DWORD PTR _a$[ebp] add eax, DWORD PTR _b$[ebp] add eax, DWORD PTR _c$[ebp] add eax, DWORD PTR _d$[ebp] add eax, DWORD PTR _e$[ebp] pop ebp ret 20 ; 00000014H _foo3@20 ENDP _TEXT ENDS PUBLIC _main EXTRN _printf:PROC ; Function compile flags: /Odtp _TEXT SEGMENT _argc$ = 8 ; size = 4 _argv$ = 12 ; size = 4 _main PROC ; 16 : int main(int argc, char *argv[]) { push ebp mov ebp, esp ; 17 : printf("foo1() = %d\n", foo1(1, 2, 3, 4, 5)); push 5 push 4 push 3 push 2 push 1 call _foo1@20 push eax push OFFSET $SG78612 call _printf add esp, 8 ; 18 : printf("foo2() = %d\n", foo2(6, 7, 8, 9, 0)); push 0 push 9 push 8 push 7 push 6 call _foo2@20 push eax push OFFSET $SG78613 call _printf add esp, 8 ; 19 : printf("foo3() = %d\n", foo3(10, 20, 30, 40, 50)); push 50 ; 00000032H push 40 ; 00000028H push 30 ; 0000001eH push 20 ; 00000014H push 10 ; 0000000aH call _foo3@20 push eax push OFFSET $SG78614 call _printf add esp, 8 ; 20 : return 0; xor eax, eax ; 21 : } pop ebp ret 0 _main ENDP _TEXT ENDS END ||< * Borland C++ Compiler プリプロセス結果およびアセンブラ出力から、"__stdcall" にdefineされている事が分かる。 アセンブラコードを生成 > bcc32 -S winapis.c コンパイル&実行 #pre||> > bcc32 winapis.c > winapis.exe foo1() = 15 foo2() = 30 foo3() = 150 ||< プリプロセス結果を生成: > cpp32 winapis.c プリプロセス結果: #code|c|> /* winapis.c 3: */ /* winapis.c 4: */int __stdcall /* winapis.c 5: */foo1(int a, int b, int c, int d, int e) /* winapis.c 6: */{ return a + b + c + d + e; } /* winapis.c 7: */ /* winapis.c 8: */int __stdcall /* winapis.c 9: */foo2(int a, int b, int c, int d, int e) /* winapis.c 10: */{ return a + b + c + d + e; } /* winapis.c 11: */ /* winapis.c 12: */int __stdcall /* winapis.c 13: */foo3(int a, int b, int c, int d, int e) /* winapis.c 14: */{ return a + b + c + d + e; } /* winapis.c 15: */ /* winapis.c 16: */int main(int argc, char *argv[]) { /* winapis.c 17: */printf("foo1() = %d\n", foo1(1, 2, 3, 4, 5)); /* winapis.c 18: */printf("foo2() = %d\n", foo2(6, 7, 8, 9, 0)); /* winapis.c 19: */printf("foo3() = %d\n", foo3(10, 20, 30, 40, 50)); /* winapis.c 20: */return 0; /* winapis.c 21: */} ||< ** アセンブラ出力(winapis.asm) #pre||> .386p ifdef ??version if ??version GT 500H .mmx endif endif model flat ifndef ??version ?debug macro endm endif ?debug S "winapis.c" ?debug T "winapis.c" _TEXT segment dword public use32 'CODE' _TEXT ends _DATA segment dword public use32 'DATA' _DATA ends _BSS segment dword public use32 'BSS' _BSS ends DGROUP group _BSS,_DATA _TEXT segment dword public use32 'CODE' foo1 proc near ?live1@0: ; ; foo1(int a, int b, int c, int d, int e) ; push ebp mov ebp,esp ; ; { return a + b + c + d + e; } ; @1: mov eax,dword ptr [ebp+8] add eax,dword ptr [ebp+12] add eax,dword ptr [ebp+16] add eax,dword ptr [ebp+20] add eax,dword ptr [ebp+24] @3: @2: pop ebp ret 20 foo1 endp foo2 proc near ?live1@48: ; ; foo2(int a, int b, int c, int d, int e) ; push ebp mov ebp,esp ; ; { return a + b + c + d + e; } ; @4: mov eax,dword ptr [ebp+8] add eax,dword ptr [ebp+12] add eax,dword ptr [ebp+16] add eax,dword ptr [ebp+20] add eax,dword ptr [ebp+24] @6: @5: pop ebp ret 20 foo2 endp foo3 proc near ?live1@96: ; ; foo3(int a, int b, int c, int d, int e) ; push ebp mov ebp,esp ; ; { return a + b + c + d + e; } ; @7: mov eax,dword ptr [ebp+8] add eax,dword ptr [ebp+12] add eax,dword ptr [ebp+16] add eax,dword ptr [ebp+20] add eax,dword ptr [ebp+24] @9: @8: pop ebp ret 20 foo3 endp _main proc near ?live1@144: ; ; int main(int argc, char *argv[]) { ; push ebp mov ebp,esp ; ; printf("foo1() = %d\n", foo1(1, 2, 3, 4, 5)); ; @10: push 5 push 4 push 3 push 2 push 1 call foo1 push eax push offset s@ call _printf add esp,8 ; ; printf("foo2() = %d\n", foo2(6, 7, 8, 9, 0)); ; push 0 push 9 push 8 push 7 push 6 call foo2 push eax push offset s@+13 call _printf add esp,8 ; ; printf("foo3() = %d\n", foo3(10, 20, 30, 40, 50)); ; push 50 push 40 push 30 push 20 push 10 call foo3 push eax push offset s@+26 call _printf add esp,8 ; ; return 0; ; xor eax,eax ; ; } ; @12: @11: pop ebp ret _main endp _TEXT ends _DATA segment dword public use32 'DATA' s@ label byte ; s@+0: db "foo1() = %d",10,0 ; s@+13: db "foo2() = %d",10,0 ; s@+26: db "foo3() = %d",10,0 align 4 _DATA ends _TEXT segment dword public use32 'CODE' _TEXT ends public foo1 public foo2 public foo3 public _main extrn __setargv__:near extrn _printf:near ?debug C 9F757569642E6C6962 ?debug C 9F757569642E6C6962 ?debug D "C:\in_vitro\apps\borland\bcc55\include\imm.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\mcx.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winsvc.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\commdlg.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\oleauto.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\propidl.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\oaidl.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\msxml.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\servprov.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\oleidl.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\urlmon.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\cguid.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\objidl.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\unknwn.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\search.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\stdlib.h" 10521 10272 ?debug D "C:\in_vitro\apps\borland\bcc55\include\objbase.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\ole2.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\prsht.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winspool.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winsmcrd.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winioctl.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\rpcnsip.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\rpcndr.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\wtypes.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winscard.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winefs.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\wincrypt.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\qos.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winsock2.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winperf.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\shellapi.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\rpcasync.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\rpcnterr.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\rpcnsi.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\rpcdcep.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\rpcdce.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\rpc.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\nb30.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\mmsystem.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\lzexpand.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\dlgs.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\ddeml.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\dde.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\cderr.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winnetwk.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winreg.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winver.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\wincon.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winnls.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\tvout.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winuser.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\pshpack1.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\wingdi.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winerror.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winbase.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\pshpack8.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\pshpack2.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\poppack.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\pshpack4.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\mem.h" 10521 10272 ?debug D "C:\in_vitro\apps\borland\bcc55\include\_loc.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\locale.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\_str.h" 10521 10272 ?debug D "C:\in_vitro\apps\borland\bcc55\include\string.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\guiddef.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\basetsd.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\mbctype.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\ctype.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\winnt.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\windef.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\stdarg.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\excpt.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\windows.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\_nfile.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\_null.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\_defs.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\_stddef.h" 10339 10240 ?debug D "C:\in_vitro\apps\borland\bcc55\include\stdio.h" 10339 10240 ?debug D "winapis.c" 15473 36482 end ||< * MinGW/MSYS * OpenWatcom Compiler(16bit) * OpenWatcom Compiler(32bit) #navi_footer|C言語系|