发新话题
打印

[转载D语言文档] 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接口定义类似这样(找个简单的):

[
    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 )

version(Windows) {

    interface IRpcChannelBuffer2 : IRpcChannelBuffer
    {
        HRESULT GetProtocolVersion (DWORD* pdwVersion);
    }

}

失去了uuid信息。只要稍作修改,在转换时保存uuid,即可以模板来模拟实现__uuidof操作符。

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
    );
}

转换为:

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为大家提供一个学习交流各种知识的平台

TOP

发新话题