【发布时间】:2015-08-10 17:07:34
【问题描述】:
我正在通过 C++ 学习 COM。来自MSDN:
应用程序必须在进行任何操作之前使用 CoInitializeEx 其他 COM 库调用内存分配函数除外。
内存分配函数在我看来是CoTaskMemAlloc和CoTaskMemFree。
但是我明白了,无论是否调用 CoInitializeEx 和 CoUninitialize 函数,我的“Hello World”都可以正常工作。在我的代码中,我使用在 combaseapi.h 标头中声明的 StringFromCLSID 函数。所以,在我看来它是一个 COM 函数。我的代码:
/* entry_point.cpp */
#include "Tools.h"
#include <objbase.h>
int main(){
HRESULT hr = ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr)){
trace("Can't initialize COM for using in the current thread.");
keep_window_opened();
return 1;
}
// {D434CF7D-2CDD-457A-A4EF-5822D629CE83}
static const CLSID clsid =
{ 0xd434cf7d, 0x2cdd, 0x457a, {
0xa4, 0xef, 0x58, 0x22, 0xd6, 0x29, 0xce, 0x83 } };
const size_t SIZE = 39;
wchar_t* wch = nullptr;
hr = ::StringFromCLSID(clsid, &wch);
if (FAILED(hr)){
trace("Can't convert CLSID to wchar_t array.");
}
else{
trace("CLSID converted to wchar_t array.");
char mch[SIZE];
size_t count = 0;
int result = ::wcstombs_s(&count, mch, wch, SIZE);
if (result){
trace("Can't convert wchar_t array to char array.");
}
else{
trace(mch);
}
::CoTaskMemFree(wch);
}
::CoUninitialize();
keep_window_opened();
return 0;
}
如果我删除了CoInitializeEx 和CoUninitialize 函数的调用,那么我的代码仍然可以工作。我预计它不会工作......
为什么StringFromCLSID 之前没有调用CoInitializeEx 也能工作?
谢谢。
【问题讨论】:
-
这听起来可能有点迂腐,但我认为这很重要:始终遵守规范为您提供最佳服务。该规则说,如果没有首先调用
CoInitializeEx,则允许Microsoft 使StringFromCLSID使您的程序崩溃;它没有发生在你身上的事实是无关紧要的。在编程语言圈中,这被称为“未定义行为”。相反,微软花费了数千小时添加多余的代码,并放弃了性能增强,因为必须保护不遵守规范的程序。 -
@Bush:您链接到的文档适用于
CoInitializeEx()的Windows Mobile 版本。CoInitializeEx()的 桌面 版本记录在 here 中,其措辞与移动版本不同。
标签: c++ winapi visual-c++ com