D语言里面,可以通过version(Windows)来兼容COM接口,不过对于__uuidof却没有相应实现。
原始COM接口定义类似这样(找个简单的):
VC++中可通过__uuidof操作符来获取COM接口中的uuid“元”信息。
转换为D接口后代码如下:
失去了uuid信息。只要稍作修改,在转换时保存uuid,即可以模板来模拟实现__uuidof操作符。
如上面代码,接口在转换时,把:
转换为:
即可,这个可以交由自动化工具完成。
由于__uuidof模板值在编译期决议,没有实际的运行期开销。
原始COM接口定义类似这样(找个简单的):
[
local,
object ,
uuid(594f31d0 - 7f19 - 11d0 - b194 - 00a0c90dc8bf)
]
interface IRpcChannelBuffer2 : IRpcChannelBuffer
{
HRESULT GetProtocolVersion
(
[ in , out ] DWORD * pdwVersion
);
}
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);
}
}
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);
}
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);
}
}
{
IID __uuidof = IIDFromStr ! ( " 594f31d0-7f19-11d0-b194-00a0c90dc8bf " );
}
version (Windows) {
interface IRpcChannelBuffer2 : IRpcChannelBuffer {
HRESULT GetProtocolVersion (DWORD * pdwVersion);
}
}
即可,这个可以交由自动化工具完成。
由于__uuidof模板值在编译期决议,没有实际的运行期开销。