COM接口IDL转换为D接口以及__uuidof实现。

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接口后代码如下:

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模板值在编译期决议,没有实际的运行期开销。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值