yidabu 2007-4-28 18:29
COM接口IDL转换为D接口以及__uuidof实现
COM接口IDL转换为D接口以及__uuidof实现知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070428点击下面网址查看原文:http://www.d-programming-language-china.org by: qiezi from: http://qiezi.javaeye.com/blog/26652 D语言里面,可以通过version(Windows)来兼容COM接口,不过对于__uuidof却没有相应实现。 原始COM接口定义类似这样(找个简单的): [Copy to clipboard] [ - ]CODE: [ local, object, uuid(594f31d0-7f19-11d0-b194-00a0c90dc8bf) ] interface IRpcChannelBuffer2 : IRpcChannelBuffer { HRESULT GetProtocolVersion ( [in,out] DWORD *pdwVersion ); } VC++中可通过__uuidof操作符来获取COM接口中的uuid“元”信息。 转换为D接口后代码如下:( 本文出处: http://www.d-programming-language-china.org ) [Copy to clipboard] [ - ]CODE: version(Windows) { interface IRpcChannelBuffer2 : IRpcChannelBuffer { HRESULT GetProtocolVersion (DWORD* pdwVersion); } } 失去了uuid信息。只要稍作修改,在转换时保存uuid,即可以模板来模拟实现__uuidof操作符。 [Copy to clipboard] [ - ]CODE: import std.c.windows.com; import std.string; import std.stdio; private: template HexStrToUbyte(char[] str) { const ubyte HexStrToUbyte = cast(ubyte)HexStrToUlong!(str); } template HexStrToUshort(char[] str) { const ushort HexStrToUshort = cast(ushort)HexStrToUlong!(str); } template HexStrToUint(char[] str) { const uint HexStrToUint = cast(uint)HexStrToUlong!(str); } template HexStrToUlong(char[] str) { static if (str.length == 1) const ulong HexStrToUlong = HexToUbyte!(str[0..1]); else const ulong HexStrToUlong = HexToUbyte!(str[length-1..length]) + 16UL * HexStrToUlong!(str[0..length-1]); } private: template HexToUbyte(char[] c) { static if (c[0] >= '0' && c[0] <= '9') const ubyte HexToUbyte = c[0] - '0'; else static if (c[0] == 'A' || c[0] == 'a') const ubyte HexToUbyte = 0xa; else static if (c[0] == 'B' || c[0] == 'b') const ubyte HexToUbyte = 0xb; else static if (c[0] == 'C' || c[0] == 'c') const ubyte HexToUbyte = 0xc; else static if (c[0] == 'D' || c[0] == 'd') const ubyte HexToUbyte = 0xd; else static if (c[0] == 'E' || c[0] == 'e') const ubyte HexToUbyte = 0xe; else static if (c[0] == 'F' || c[0] == 'f') const ubyte HexToUbyte = 0xf; } template HexToUbyte_bug(char c) { static if (c >= '0' && c <= '9') const ubyte HexToUbyte1 = c - '0'; else static if (c == 'A' || c == 'a') const ubyte HexToUbyte1 = 0xa; else static if (c == 'B' || c == 'b') const ubyte HexToUbyte1 = 0xb; else static if (c == 'C' || c == 'c') const ubyte HexToUbyte1 = 0xc; else static if (c == 'D' || c == 'd') const ubyte HexToUbyte1 = 0xd; else static if (c == 'E' || c == 'e') const ubyte HexToUbyte1 = 0xe; else static if (c == 'F' || c == 'f') const ubyte HexToUbyte1 = 0xf; } template IIDFromStr(char[] str) { const IID IIDFromStr = { HexStrToUint!(str[0..8]), HexStrToUshort!(str[9..13]), HexStrToUshort!(str[14..18]), [ HexStrToUbyte!(str[19..21]), HexStrToUbyte!(str[21..23]), HexStrToUbyte!(str[24..26]), HexStrToUbyte!(str[26..28]), HexStrToUbyte!(str[28..30]), HexStrToUbyte!(str[30..32]), HexStrToUbyte!(str[32..34]), HexStrToUbyte!(str[34..36]) ] }; } template __uuidof(T:IUnknown) { IID __uuidof = IIDFromStr!("00000000-0000-0000-C000-000000000046"); } template __uuidof(T:IClassFactory) { IID __uuidof = IIDFromStr!("00000001-0000-0000-C000-000000000046"); } void main() { IID iu = __uuidof!(IUnknown); IID icp = __uuidof!(IClassFactory); writefln(iu.Data1); writefln(iu.Data2); writefln(iu.Data3); writefln(iu.Data4); } 如上面代码,接口在转换时,把: [ local, object, uuid(594f31d0-7f19-11d0-b194-00a0c90dc8bf) ] interface IRpcChannelBuffer2 : IRpcChannelBuffer { HRESULT GetProtocolVersion ( [in,out] DWORD *pdwVersion ); } 转换为: [Copy to clipboard] [ - ]CODE: template __uuidof(T:IRpcChannelBuffer2) { IID __uuidof = IIDFromStr!("594f31d0-7f19-11d0-b194-00a0c90dc8bf"); } version (Windows) { interface IRpcChannelBuffer2 : IRpcChannelBuffer { HRESULT GetProtocolVersion (DWORD* pdwVersion); } } 即可,这个可以交由自动化工具完成。 由于__uuidof模板值在编译期决议,没有实际的运行期开销。( lastupdate:20070428 最新文章请访问http://www.d-programming-language-china.org )关于一大步成功社区:yidabu提倡在交流中学习,在分享中提高收集感兴趣的知识,写下心得,通过网络与别人一起分享理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台