对于编程,我发现自己还很菜,还有很多东西要学习。今天又从我们公司那位牛人那里学了一课,什么叫程序员。有句话说的好:“如果你用了所有的智慧来写代码,那么你就没有足够的能力来调试程序”。这句话对于我们这些比较菜的程序员来说,有点伤感,不过的确是一个事实。作为一个程序员,不仅仅只是能完成功能,而是要很好的完成,更重要的是当功能出现问题时,你要能很好的找到原因并解决它。
下面是今天发生在我身上的一件事情,对于COM的使用我们都很熟悉,最基本的要求是CoInitialize(), CoUninitialize()。而对于CoInitializeSecurity()这个函数可能不是很熟悉,而我今天要讲的也正是这个函数,今天也在它身上花了大半天的时间。下面是这个函数在MSDN中的定义:
Registers security and sets the default security values for the process. This function is called exactly once per process, either explicitly or implicitly. It can be called by the client, server, or both. For legacy applications and other applications that do not explicitly call CoInitializeSecurity, COM calls this function implicitly with values from the registry. If you set processwide security using the registry and then call CoInitializeSecurity, the AppID registry values will be ignored and the CoInitializeSecurity values will be used.
注册并设置进程的默认的安全值。该函数只被每个进程确切的调用一次,以显式或隐式的方式。它可以被客户端,服务器端或是两边都调用。对于非COM的应用程序不应该显式的被调用,但是对于COM应用程序该函数会隐式的从注册表读取参数来调用。如果你使用注册表设置进程级的安全然后调用CoInitializeSecurity, 那么AppID的注册表值会被忽略而使用CoInitializeSecurity值。从这段话中,我们可以知道两个信息,一,CoInitializeSecurity函数用于设置进程安全;二,只能被进程调用一次。第一点是说明用途,而第二点说明用法。很简单,只要在CoInitialize()后面调用一下就可以。但是请记住一定要用下面的方式去验证返回值:
HRESULT hr;
hr = CoInitialzieSecurity();
if (SUCCEED(hr) || RPC_E_TOO_LATE == hr)
{
do your work;
}
This function supports the standard return value E_INVALIDARG, as well as the following:
S_OK
Indicates success.
RPC_E_TOO_LATE
CoInitializeSecurity has already been called.
RPC_E_NO_GOOD_SECURITY_PACKAGES
asAuthSvc was not NULL, and none of the authentication services in the list could be registered. Check the results saved in asAuthSvc for authentication service–specific error codes.
E_OUT_OF_MEMORY
Out of memory.
strncpy_s( dest, _countof(dest), src, count );
并且这句代码不是在所有平台上都有问题。
这个我今天也是在牛人的帮助下才找出来的,而最大地问题是它出现在同一是双核的只是速度不同的w2k3机器上,一台百分百返回S_OK; 而另一台百分百返回RPC_E_TOO_LATE,而且用的同样的代码。所以初步怀疑是多线程时序的问题。不得不承认调试很难^_^。顺便提一句,大家看到这样的代码hang在那里会有什么想法: