読者です 読者をやめる 読者になる 読者になる

Windows Driver Kit for Windows 7 and Windows Server 2008 R2

RTMのはずなんだけど、

c:\winddk\7600.16385.0\inc\api\propkeydef.h(32) : error C2664: 'memcmp' : cannot convert parameter 1 from 'const GUID' to 'const void *'
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

なんていう嫌なエラーが出る。仕方がないので、propkeydef.hを見てみると、

23: #ifndef IsEqualPropertyKey
24: #define IsEqualPropertyKey(a, b)   (((a).pid == (b).pid) && IsEqualIID((a).fmtid, (b).fmtid) )
25: #endif  // IsEqualPropertyKey
26:
27: #ifndef _PROPERTYKEY_EQUALITY_OPERATORS_
28: #define _PROPERTYKEY_EQUALITY_OPERATORS_
29: #ifdef __cplusplus
30: extern "C++"
31: {
32: __inline int operator == (REFPROPERTYKEY pkeyOne, REFPROPERTYKEY pkeyOther) { return IsEqualPropertyKey(pkeyOne, pkeyOther); }
33: __inline int operator != (REFPROPERTYKEY pkeyOne, REFPROPERTYKEY pkeyOther) { return !(pkeyOne == pkeyOther); }
34: }
35: #endif // __cplusplus
36: #endif // _PROPERTYKEY_EQUALITY_OPERATORS_

怪しいのは、IsEqualIID。これの定義を探してみると、winddi.hの74行目あたりから、

74: #ifndef IsEqualGUID
75:     #define IsEqualGUID(guid1, guid2) \
76:         (!memcmp((guid1), (guid2), sizeof(GUID)))
77: #endif // !defined(IsEqualGUID)
78:
79: #ifndef IsEqualIID
80:     #define IsEqualIID IsEqualGUID
81: #endif // !defined(IsEqualIID)

という実装があった。これは、結論から言えば、propkeydef.h 5行目からの、

 5: #ifndef REFPROPERTYKEY
 6: #ifdef __cplusplus
 7: #define REFPROPERTYKEY const PROPERTYKEY &
 8: #else // !__cplusplus
 9: #define REFPROPERTYKEY const PROPERTYKEY * __MIDL_CONST
10: #endif // __cplusplus
11: #endif //REFPROPERTYKEY

で、REFPROPERTYKEYが参照で定義されていることが原因っぽい。ということで、これを見越して、事前に

int memcmp(const GUID& a, const GUID& b, size_t size);

としてから、winddi.hをインクルードするようにしたらエラーは出なくなった。
さらに、手元のコードの場合、結局は、これらの実装を一度も使ってなかったため、このmemcmpの実装はいらなかった。

しかし、何でこんなバグが残るのやら・・・。