仿真VC++提供的关键字__uuidof
2008-07-02 20:05
295 查看
这个技巧不是针对VC++ 6.0缺陷的,而是针对VC++扩展语法的。这个技巧的来由,是为了某些希望有一天有可能要脱离Visual C++环境进行开发的人员。为了脱离VC++,你需要谨慎使用它的所有扩展语法。例如本文讨论的__uuidof。我们先来看看一个例子:
class __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BA")) Class;
struct __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BB")) Interface;
void test()
{
CLSID clsid = __uuidof(Class);
IID iid = __uuidof(Interface);
...
}
这比起你以前定义uuid的方法简单多了吧?可惜,这样好用的东西,它只在VC++中提供。不过没有关系,我们这里介绍一个 技巧,可以让你在几乎所有C++编译器中都可以这样方便的使用__uuidof。这里没有说是所有,是因为我们使用了模板特化技术,可能存在一些比较“古 老”的C++编译器,不支持该特性。
也许你已经迫不及待了。好,让我们来看看:
#include <string>
#include <cassert>
inline
STDMETHODIMP_(GUID) GUIDFromString(LPOLESTR lpsz)
{
HRESULT hr;
GUID guid;
if (lpsz[0] == '{')
{
hr = CLSIDFromString(lpsz, &guid);
}
else
{
std::basic_string<OLECHAR> strGuid;
strGuid.append(1, '{');
strGuid.append(lpsz);
strGuid.append(1, '}');
hr = CLSIDFromString((LPOLESTR)strGuid.c_str(), &guid);
}
assert(hr == S_OK);
return guid;
}
template <class Class>
struct _UuidTraits {
};
#define _DEFINE_UUID(Class, uuid) /
template <> /
struct _UuidTraits<Class> { /
static const GUID& Guid() { /
static GUID guid = GUIDFromString(L ## uuid); /
return guid; /
} /
}
#define __uuidof(Class) _UuidTraits<Class>::Guid()
#define DEFINE_CLSID(Class, guid) /
class Class; /
_DEFINE_UUID(Class, guid)
#define DEFINE_IID(Interface, iid) /
struct Interface; /
_DEFINE_UUID(Interface, iid)
这样一来,就已经模拟出一个__uuidof关键字。我们可以很方便进行uuid的定义。举例如下:
DEFINE_CLSID(Class, "{B372C9F6-1959-4650-960D-73F20CD479BA}");
DEFINE_IID(Interface, "{B372C9F6-1959-4650-960D-73F20CD479BB}");
void test()
{
CLSID clsid = __uuidof(Class);
IID iid = __uuidof(Interface);
...
}
在VC++中,为了与其他编译器以相同的方式来进行uuid的定义,我们不直接使用__declspec(uuid),而是也定义DEFINE_CLSID, DEFINE_IID宏:
#define DEFINE_CLSID(Class, clsid) /
class __declspec(uuid(clsid)) Class
#define DEFINE_IID(Interface, iid) /
struct __declspec(uuid(iid)) Interface
这样一来,我们已经在所有包含VC++在内的支持模板特化技术的编译器中,提供了__uuidof关键字。通过它可以进一步简化你在C++语言中实现COM组件的代价。
附注:关于本文使用的C++模板的特化技术,详细请参阅C++文法方面的书籍,例如《C++ Primer》。其实这个技巧在C++标准库——STL中有一个专门的名字:traits(萃取),你可以在很多介绍STL的书籍中见到相关的介绍。
转载自 许式伟的专栏 http://blog.csdn.net/xushiweizh/archive/2006/11/16/1388949.aspx
class __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BA")) Class;
struct __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BB")) Interface;
void test()
{
CLSID clsid = __uuidof(Class);
IID iid = __uuidof(Interface);
...
}
这比起你以前定义uuid的方法简单多了吧?可惜,这样好用的东西,它只在VC++中提供。不过没有关系,我们这里介绍一个 技巧,可以让你在几乎所有C++编译器中都可以这样方便的使用__uuidof。这里没有说是所有,是因为我们使用了模板特化技术,可能存在一些比较“古 老”的C++编译器,不支持该特性。
也许你已经迫不及待了。好,让我们来看看:
#include <string>
#include <cassert>
inline
STDMETHODIMP_(GUID) GUIDFromString(LPOLESTR lpsz)
{
HRESULT hr;
GUID guid;
if (lpsz[0] == '{')
{
hr = CLSIDFromString(lpsz, &guid);
}
else
{
std::basic_string<OLECHAR> strGuid;
strGuid.append(1, '{');
strGuid.append(lpsz);
strGuid.append(1, '}');
hr = CLSIDFromString((LPOLESTR)strGuid.c_str(), &guid);
}
assert(hr == S_OK);
return guid;
}
template <class Class>
struct _UuidTraits {
};
#define _DEFINE_UUID(Class, uuid) /
template <> /
struct _UuidTraits<Class> { /
static const GUID& Guid() { /
static GUID guid = GUIDFromString(L ## uuid); /
return guid; /
} /
}
#define __uuidof(Class) _UuidTraits<Class>::Guid()
#define DEFINE_CLSID(Class, guid) /
class Class; /
_DEFINE_UUID(Class, guid)
#define DEFINE_IID(Interface, iid) /
struct Interface; /
_DEFINE_UUID(Interface, iid)
这样一来,就已经模拟出一个__uuidof关键字。我们可以很方便进行uuid的定义。举例如下:
DEFINE_CLSID(Class, "{B372C9F6-1959-4650-960D-73F20CD479BA}");
DEFINE_IID(Interface, "{B372C9F6-1959-4650-960D-73F20CD479BB}");
void test()
{
CLSID clsid = __uuidof(Class);
IID iid = __uuidof(Interface);
...
}
在VC++中,为了与其他编译器以相同的方式来进行uuid的定义,我们不直接使用__declspec(uuid),而是也定义DEFINE_CLSID, DEFINE_IID宏:
#define DEFINE_CLSID(Class, clsid) /
class __declspec(uuid(clsid)) Class
#define DEFINE_IID(Interface, iid) /
struct __declspec(uuid(iid)) Interface
这样一来,我们已经在所有包含VC++在内的支持模板特化技术的编译器中,提供了__uuidof关键字。通过它可以进一步简化你在C++语言中实现COM组件的代价。
附注:关于本文使用的C++模板的特化技术,详细请参阅C++文法方面的书籍,例如《C++ Primer》。其实这个技巧在C++标准库——STL中有一个专门的名字:traits(萃取),你可以在很多介绍STL的书籍中见到相关的介绍。
转载自 许式伟的专栏 http://blog.csdn.net/xushiweizh/archive/2006/11/16/1388949.aspx
相关文章推荐
- 仿真VC++提供的关键字__uuidof
- 更好地仿真VC++关键字__uuidof
- 仿真VC++提供的关键字__uuidof
- C++编译期函数/变量检测技术,仿真VC关键字__if_exists
- C++编译期函数/变量检测技术,仿真VC关键字__if_exists
- 有效的使用和设计COM智能指针——条款27:考虑__uuidof与uuid在关键字在不同编译器上的兼容问题
- VC下这样创建实例m_pRecordset.CreateInstance(_uuidof(Connection))不一定成功!...
- VC下这样创建实例m_pRecordset.CreateInstance(_uuidof(Connection))不一定成功!...
- C++ 中提供的override 关键字
- List of Best Open Souce projects written in VC++/MFC
- VC用MYSQL提供的LIB查询数据库
- Hot key of VC
- 编码解码器无法使用提供的流类型 The codec cannot use the type of stream provided
- VC++关键字-"__declspec"
- contain remnants of that class,VC++中怎样彻底删除一个由ClassWizard生成的类
- My study of VC++ ( Paint refered )
- vc提供的遍历目录的函数 FindFirstFile
- HOWTO: Recover the Problem of fschk.exe : unable to resolve UUID=”
- UISplitViewController in portrait on iPhone shows detail VC instead of master
- VC 关键字 __asm