#import から TLIBIMP.EXE への C++ コードの移行
TLIBIMP.EXE への移動
このトピックでは、タイプ ライブラリを正しくインポートするために #import
ではなく TLIBIMP.EXE を使用するようにした場合に解決しなければならない問題について説明します。#import
を使用しようとすると、"W8137 非推奨の #import 指令が検出されました。代わりに、TLIBIMP ユーティリティを使用してください。" という警告が C++ コンパイラから出力されます。
TLIBIMP.EXE と #import
指令では、以下のように、指定された CoClass に対して生成される GUID が異なります。
- #import の場合:
__uuidof(CoClass)
で CoClass の GUID が返されます。 - TLIBIMP の場合:
__uuidof(CoClass)
で CoClass のデフォルト インターフェイスの GUID が返されます。
たとえば、次のような .ridl コード断片で表されるタイプ ライブラリの #import
で生成されるコードを以下に示しましょう。
[
uuid(ECD2547D-5BC5-49C6-A7D1-9D55C0A9F0DF),
version(1.0)
]
library Project14
{
importlib("stdole2.tlb");
coclass CoClass1;
interface Interface1;
[
uuid(AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA),
dual,
oleautomation
]
interface Interface1: IDispatch
{
};
[
uuid(cccccccc-cccc-cccc-cccc-cccccccccccc)
]
coclass CoClass1
{
[default] interface Interface1;
};
};
上記タイプ ライブラリの CoClass1 については、#import
で以下の宣言が(裏で)生成されます。
struct __declspec(uuid("cccccccc-cccc-cccc-cccc-cccccccccccc"))
CoClass1;
つまり、#import
を使用する場合は、型 CoClass1 に関連付けられる GUID がまさにその CoClass の GUID になります。
一方、TLIBIMP では、CoClass1 の以下の宣言が生成されます。
interface DECLSPEC_UUID("{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}") Interface1;
typedef Interface1 CoClass1;
そのため、#import
と __uuidof(CoClass1)
を一緒に使用するコードは、TLIBIMP で生成されたバインディングを使用する場合には動作しません。
たとえば、以下のコードは動作しません。
#include <stdio.h>
#import "test.tlb"
using namespace TestLibrary;
int main()
{
GUID g = __uuidof(CoClass1);
printf("GUID of CoClass1"
" = {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
g.Data1, g.Data2, g.Data3,
g.Data4[0], g.Data4[1],
g.Data4[2], g.Data4[3],
g.Data4[4], g.Data4[5],
g.Data4[6], g.Data4[7]);
return 0;
}
そのため、#import
を使用するのをやめて、TLIBIMP で生成されたユニットを使用する場合は、__uuidof(CoClassName)
を利用して CoClass の GUID を返すコードに注意する必要があります。コードでは、TLIBIMP で CoClass に対して生成された CLSID_xxxx 形式の GUID を代わりに使用しなければなりません。
つまり、上記コードの場合は以下のように書き換えます。
#include <stdio.h>
//#import "test.tlb"
#include "TestLibrary_TLB.h"
//using namespace TestLibrary;
int main()
{
// GUID g = __uuidof(CoClass1);
GUID g = CLSID_CoClass1;
printf("GUID of CoClass1"
" = {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
g.Data1, g.Data2, g.Data3,
g.Data4[0], g.Data4[1],
g.Data4[2], g.Data4[3],
g.Data4[4], g.Data4[5],
g.Data4[6], g.Data4[7]);
return 0;
}