From: Vincent Fatica on 7 Sep 2009 15:11 On Mon, 7 Sep 2009 21:44:17 +0300, "Alex Blekhman" <tkfx.REMOVE(a)yahoo.com> wrote: |Even if you use a custom entry point it is still must conform to |the expected signature of [w]WinMain or [w]main. Also, calling |convention must be __stdcall for Windows subsystem and __cdecl for |console subsystem. To avoid the RTL I often use a custom entry point and I often violate the conventions you mentioned. I haven't gotten into trouble yet. Please elaborate. -- - Vince
From: Alex Blekhman on 7 Sep 2009 16:58 "Vincent Fatica" wrote: > To avoid the RTL I often use a custom entry point and I often > violate the conventions you mentioned. I haven't gotten into > trouble yet. Please elaborate. The linker requires that the entry point would be of certain signature. It means that the code it generates around the call expects a predefined number of parameters and a predefined calling convention. I think that calling stack gets corrupted upon exit from the entry point. I'm not sure why there is no diagnostic message issued by the system, though. May be it is because there is no CRT to report it in the convenient way, or the process is already on its way down when it happens, so no point to report it, or whatever else. But it seems to me unclean to violate this requirement while the linker's documentation explicitly insists on it. Alex
From: Vincent Fatica on 7 Sep 2009 18:01 On Mon, 7 Sep 2009 23:58:19 +0300, "Alex Blekhman" <tkfx.REMOVE(a)yahoo.com> wrote: |"Vincent Fatica" wrote: |> To avoid the RTL I often use a custom entry point and I often |> violate the conventions you mentioned. I haven't gotten into |> trouble yet. Please elaborate. | |The linker requires that the entry point would be of certain |signature. It means that the code it generates around the call |expects a predefined number of parameters and a predefined calling |convention. I think that calling stack gets corrupted upon exit |from the entry point. I'm not sure why there is no diagnostic |message issued by the system, though. May be it is because there |is no CRT to report it in the convenient way, or the process is |already on its way down when it happens, so no point to report it, |or whatever else. But it seems to me unclean to violate this |requirement while the linker's documentation explicitly insists on |it. Can you point me to that linker documentation? If you look at the CRT startup routines (the typical entry points, crtexe.c) for EXEs, you see that they are __cdecl, taking, no args and returning an int. They examine a command line, do their thing, and eventually call main, wmain, or WinMain. So the signatures of main, wmain, and WinMain are very important. But if you're not using the CRT startup routines and you are specifying an entry point, it would seem that int __cdecl ...(void) is appropriate. -- - Vince
From: xiaosi on 8 Sep 2009 01:29 Besides call convention, ExitProcess should be used instead of return, because both tmainCRTStartup and tWinMainCRTStartup call kernel32!ExitProcess(status) after tmain or tWinMain return status. If you use Common Dialog Box in your app, and return (instead of ExitProcess) to exit app, the process will not exit (the thread of Common Dialog Box is still existing). #pragma comment(linker, "/subsystem:windows") #pragma comment(linker, "/entry:mywinmain") int __stdcall mywinmain() { .... ExitProcess(msg.wParam); } #pragma comment(linker, "/subsystem:console") #pragma comment(linker, "/entry:mymain") int __cdecl mymain() { .... ExitProcess(status); } "Vincent Fatica" <vince(a)blackholespam.net> wrote: > On Mon, 7 Sep 2009 21:44:17 +0300, "Alex Blekhman" <tkfx.REMOVE(a)yahoo.com> > wrote: > > |Even if you use a custom entry point it is still must conform to > |the expected signature of [w]WinMain or [w]main. Also, calling > |convention must be __stdcall for Windows subsystem and __cdecl for > |console subsystem. > > To avoid the RTL I often use a custom entry point and I often violate the > conventions you mentioned. I haven't gotten into trouble yet. Please > elaborate. > -- > - Vince
From: xiaosi on 8 Sep 2009 01:32
One day I dumpbin /headers /exports ntdll.dll > exports_ntdll.txt, and find ntdll.dll has many "built-in" crt functions. When system loads an app, it always firstly maps ntdll.dll to the app's process. This means every app has these "built-in" crt functions, so why bother to import these functions from the crt lib (except using inline for speed). wcstoul/wcstol/strtoul/strtol are also "built-in" in ntdll.dll. 1180 49B 0000E5C6 _CIcos = __CIcos 1181 49C 0000E682 _CIlog = __CIlog 1182 49D 0000E002 _CIpow = __CIpow 1183 49E 000012D1 _CIsin = __CIsin 1184 49F 0000137F _CIsqrt = __CIsqrt 1185 4A0 0002C8A2 __isascii = ___isascii 1186 4A1 0006F64B __iscsym = ___iscsym 1187 4A2 0006F605 __iscsymf = ___iscsymf 1188 4A3 0006F5F3 __toascii = ___toascii 1189 4A4 0000143B _alldiv = __alldiv 1190 4A5 000014E5 _alldvrm = __alldvrm 1191 4A6 000015C4 _allmul = __allmul 1192 4A7 000015F8 _alloca_probe = __alloca_probe 1193 4A8 00001635 _allrem = __allrem 1194 4A9 000016E9 _allshl = __allshl 1195 4AA 00001708 _allshr = __allshr 1196 4AB 0006F691 _atoi64 = __atoi64 1197 4AC 00001729 _aulldiv = __aulldiv 1198 4AD 00001791 _aulldvrm = __aulldvrm 1199 4AE 00001826 _aullrem = __aullrem 1200 4AF 0000189B _aullshr = __aullshr 1201 4B0 000015F8 _chkstk = __alloca_probe 1202 4B1 0007B048 _fltused = __fltused 1203 4B2 000018BA _ftol = __ftol 1204 4B3 0006F80D _i64toa = __i64toa 1205 4B4 0006F92F _i64tow = __i64tow 1206 4B5 0002E964 _itoa = __itoa 1207 4B6 0002DC81 _itow = __itow 1208 4B7 0006F989 _lfind = __lfind 1209 4B8 0006F74E _ltoa = __ltoa 1210 4B9 0006F867 _ltow = __ltow 1211 4BA 000018E1 _memccpy = __memccpy 1212 4BB 0006F9C2 _memicmp = __memicmp 1213 4BC 0006F9D2 _snprintf = __snprintf 1214 4BD 0001BBCA _snwprintf = __snwprintf 1215 4BE 0006FA30 _splitpath = __splitpath 1216 4BF 00012E44 _strcmpi = __stricmp 1217 4C0 00012E44 _stricmp = __stricmp 1218 4C1 0006FB78 _strlwr = __strlwr 1219 4C2 0001987D _strnicmp = __strnicmp 1220 4C3 0006FBA5 _strupr = __strupr 1221 4C4 0006FBD2 _tolower = __tolower 1222 4C5 0006FC1F _toupper = __toupper 1223 4C6 0006F845 _ui64toa = __ui64toa 1224 4C7 0006F967 _ui64tow = __ui64tow 1225 4C8 0006F77A _ultoa = __ultoa 1226 4C9 0006F893 _ultow = __ultow 1227 4CA 0002FB67 _vsnprintf = __vsnprintf 1228 4CB 0006FC31 _vsnwprintf = __vsnwprintf 1229 4CC 00013358 _wcsicmp = __wcsicmp 1230 4CD 00024849 _wcslwr = __wcslwr 1231 4CE 000181CD _wcsnicmp = __wcsnicmp 1232 4CF 0006FCA7 _wcsupr = __wcsupr 1233 4D0 0006FCDD _wtoi = __wtoi 1234 4D1 0006FCED _wtoi64 = __wtoi64 1235 4D2 0003684A _wtol = __wtol 1236 4D3 0006FD8A abs = _labs 1237 4D4 00001934 atan = _atan 1238 4D5 00024889 atoi = _atoi 1239 4D6 00024896 atol = _atol 1240 4D7 000151D3 bsearch = _bsearch 1241 4D8 000019D7 ceil = _ceil 1242 4D9 0000E5DA cos = _cos 1243 4DA 0006FD9F fabs = _fabs 1244 4DB 00001B18 floor = _floor 1245 4DC 0006F518 isalnum = _isalnum 1246 4DD 0006F3DC isalpha = _isalpha 1247 4DE 0006F5C0 iscntrl = _iscntrl 1248 4DF 0002C879 isdigit = _isdigit 1249 4E0 0006F588 isgraph = _isgraph 1250 4E1 0006F447 islower = _islower 1251 4E2 0006F550 isprint = _isprint 1252 4E3 0006F4E5 ispunct = _ispunct 1253 4E4 0006F4B2 isspace = _isspace 1254 4E5 0006F414 isupper = _isupper 1255 4E6 0006FE57 iswalpha = _iswalpha 1256 4E7 000269D1 iswctype = _iswctype 1257 4E8 00026A75 iswdigit = _iswdigit 1258 4E9 0006FE72 iswlower = _iswlower 1259 4EA 0006FEA5 iswspace = _iswspace 1260 4EB 0006FE8A iswxdigit = _iswxdigit 1261 4EC 0006F47A isxdigit = _isxdigit 1262 4ED 0006FD8A labs = _labs 1263 4EE 0000E67E log = _log 1264 4EF 0002490C mbstowcs = _mbstowcs 1265 4F0 00001C60 memchr = _memchr 1266 4F1 00001D07 memcmp = _memcmp 1267 4F2 00001DB3 memcpy = _memcpy 1268 4F3 000020F5 memmove = _memmove 1269 4F4 00002435 memset = _memset 1270 4F5 0000DFFD pow = _pow 1271 4F6 000203B8 qsort = _qsort 1272 4F7 000012E5 sin = _sin 1273 4F8 00025BA4 sprintf = _sprintf 1274 4F9 00001393 sqrt = _sqrt 1275 4FA 0006FEBD sscanf = _sscanf 1276 4FB 0000249D strcat = _strcat 1277 4FC 0000E7ED strchr = _strchr 1278 4FD 00002583 strcmp = _strcmp 1279 4FE 0000248D strcpy = _strcpy 1280 4FF 00002608 strcspn = _strcspn 1281 500 00002645 strlen = _strlen 1282 501 000026C0 strncat = _strncat 1283 502 000027E5 strncmp = _strncmp 1284 503 0000281D strncpy = _strncpy 1285 504 0000291D strpbrk = _strpbrk 1286 505 00002956 strrchr = _strrchr 1287 506 0000297D strspn = _strspn 1288 507 0000E75E strstr = _strstr 1289 508 000700B2 strtol = _strtol 1290 509 000700D1 strtoul = _strtoul 1291 50A 000184BB swprintf = _swprintf 1292 50B 000029CE tan = _tan 1293 50C 0006FBE4 tolower = _tolower 1294 50D 00023D13 toupper = _toupper 1295 50E 0002A826 towlower = _towlower 1296 50F 000700F0 towupper = _towupper 1297 510 00020304 vDbgPrintEx = _vDbgPrintEx(a)16 1298 511 0001EA5B vDbgPrintExWithPrefix = _vDbgPrintExWithPrefix(a)20 1299 512 00070104 vsprintf = _vsprintf 1300 513 00018112 wcscat = _wcscat 1301 514 00014962 wcschr = _wcschr 1302 515 00035424 wcscmp = _wcscmp 1303 516 00012F40 wcscpy = _wcscpy 1304 517 000356EE wcscspn = _wcscspn 1305 518 0000FE2A wcslen = _wcslen 1306 519 00018B24 wcsncat = _wcsncat 1307 51A 0001E40F wcsncmp = _wcsncmp 1308 51B 0001055F wcsncpy = _wcsncpy 1309 51C 00070162 wcspbrk = _wcspbrk 1310 51D 00014671 wcsrchr = _wcsrchr 1311 51E 000701AB wcsspn = _wcsspn 1312 51F 0002380F wcsstr = _wcsstr 1313 520 00029F03 wcstol = _wcstol 1314 521 000701F9 wcstombs = _wcstombs 1315 522 00034D91 wcstoul = _wcstoul "Vincent Fatica" <vince(a)blackholespam.net> wrote: > Thanks for that. After grep-ing through an archive of projects for "BOOL > bInQuotes" I'm embarrassed to admit how many times I have done something > similar. :-) > > Have you got any other tips on avoiding the RTL? > > wsprintf() is invaluable as are the lstr* functions (now I've learned that some > of the wcs* functions have intrinsic/inline versions). > > I have often wanted something to turn a string into a number. If I insist on > avoiding the RTL, I use StrToIntEx and feel a bit guilty dragging in shlwapi.dll > for only that reason. > -- > - Vince |