设为首页 加入收藏

TOP

C标准库源码解读(VC9.0版本)――assert.h(三)
2014-11-23 23:18:09 】 浏览:4597
Tags:标准 源码 解读 VC9.0 版本 assert.h
e to do the actual output.The macro must expand to a void expression. The program can containan expression such as (assert (O < X) , x < y) . That rules out use of theif statement, for example. Any testing must make use of one of theconditional operators within an expression.The macro should expand to efficient and compact code. Otherwise,programmers will avoid writing assertions. This version always makesa function call that passes five arguments.
为什么使用fprintf不被接受?这里给出的一个原因是fprintf的某些实现会有可能会使用到assert。但微软搞什么呢,他应该是觉得,我自己写的fprintf不会使用到assert,我不管你的标准,方便就好,我只能这么理解了。
接下来,如果不是应用台程序,程序处理有不少对要输出的字符串处理的代码段,GetModuleFIleName, _tcscpy_s, _tcscat_s, _tcslen都有使用。
在这里先吐下槽,经常看到有人拿个C语言题目:请写一个库函数strcpy。然后是3分、5分、7分、10分的答案:
[cpp]
char * strcpy( char *strDest, const char *strSrc )
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest;
 while( (*strDest++ = * strSrc++) != ‘/0’ );
  return address;
}
现在我觉得,如果assert是要调用strcpy?怎么办?给答案的考官有考虑这个么?
处理好字符串然后调用:
[cpp]
nCode = __crtMessageBox(assertbuf,
_T("Microsoft Visual C++ Runtime Library"),
MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
我们直觉肯定知道这是弹出一个窗口显示信息,然后用户选择点击哪个按钮返回对应值,但这可不是windowsAPI函数,需要再跟踪进去,到底干了什么。源代码在ctrmbox.c里。源代码也不需要一行行解析,有一个原则就是,这是底层函数,基本上都直接使用API了,肯定不会使用其他库函数——因为这个函数在实现其他库函数时要使用!看完差不多就明白了,从USER32.dll取得几个函数的地址,以函数指针形式调用弹出窗口。问题来了:为什么它不直接调用函数 而要LoadLibrary然后GetProcAddress成函数指针,再通过函数指针调用。按道理来说(我从一些windows系统理论的书看到的),Kernel32.dll和User32.dll的地址在加载系统的时候就定了,而且是按固定虚拟地址加载(按windows核心 编程作者经验所说)。再想一想,我觉得可能的解释是:为了防止不同版本的User32.dll库加载有可能的变化,Jeffrey Richter也只是说那是他的经验,微软并没有表明要加载到固定地址。但是Kernel32.dll应该就不会有什么变化的了,只要能兼容的都需要从相同的地址加载,这样应该说得过去。附__crtMessageBox代码:
[cpp]
#ifdef _UNICODE
int __cdecl __crtMessageBoxW(
#else /* _UNICODE */
int __cdecl __crtMessageBoxA(
#endif /* _UNICODE */
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
)
{
typedef int (APIENTRY *PFNMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT);
typedef HWND (APIENTRY *PFNGetActiveWindow)(void);
typedef HWND (APIENTRY *PFNGetLastActivePopup)(HWND);
typedef HWINSTA (APIENTRY *PFNGetProcessWindowStation)(void);
typedef BOOL (APIENTRY *PFNGetUserObjectInformation)(HANDLE, int, PVOID, DWORD, LPDWORD);
void *pfn = NULL;
void *enull = _encoded_null();
static PFNMessageBox pfnMessageBox = NULL;
static PFNGetActiveWindow pfnGetActiveWindow = NULL;
static PFNGetLastActivePopup pfnGetLastActivePopup = NULL;
static PFNGetProcessWindowStation pfnGetProcessWindowStation = NULL;
static PFNGetUserObjectInformation pfnGetUserObjectInformation = NULL;
HWND hWndParent = NULL;
BOOL fNonInteractive = FALSE;
HWINSTA hwinsta=NULL;
USEROBJECTFLAGS uof;
DWORD nDummy;
if (NULL == pfnMessageBox)
{
HMODULE hlib=LoadLibrary(_T("USER32.DLL"));
if(hlib==NULL)
{
return 0;
}
if (NULL == (pfn =
#ifdef _UNICODE
GetProcAddress(hlib, "MessageBoxW")))
#else /* _UNICODE */
GetProcAddress(hlib, "MessageBoxA")))
#endif /* _UNICODE */
return 0;
pfnMessageBox = (PFNMessageBox) _encode_pointer(pfn);
pfnGetActiveWindow = (PFNGetActiveWindow)
_encode_pointer(GetProcAddress(hlib, "GetActiveWindow"))
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇[C和指针]不定参数 下一篇[Slackware]Build Broadcom 802.1..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目