Migrating C++ Code from #import to TLIBIMP.EXE
Go Up to TLIBIMP.EXE
This topic describes issues that you need to resolve when you change from using #import
to using TLIBIMP.EXE in order to correctly import a type library. If you attempt to use #import
, the C++ compiler emits the warning W8137 Deprecated #import directive encountered. Please use the TLIBIMP utility instead. (C++).
TLIBIMP.EXE and the #import
directive generate different GUIDs for a given coclass:
- With #import:
__uuidof(CoClass)
returns the GUID of the CoClass. - With TLIBIMP:
__uuidof(CoClass)
returns the GUID of the default interface of the CoClass.
For example, here is the code generated by #import
for the type library represented by the following .ridl snippet:
[
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;
};
};
For CoClass1 from the type library above, #import
generates the following declaration (behind the scenes):
struct __declspec(uuid("cccccccc-cccc-cccc-cccc-cccccccccccc"))
CoClass1;
In other words, when you use #import
, the GUID associated with the type CoClass1 is indeed the GUID of the CoClass.
TLIBIMP, however, generates the following declaration for CoClass1:
interface DECLSPEC_UUID("{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}") Interface1;
typedef Interface1 CoClass1;
So code that uses __uuidof(CoClass1)
with #import
does not work when using the binding generated by TLIBIMP.
For example, following code does not work:
#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;
}
So when switching from #import
to a unit generated by TLIBIMP, you must watch out for code that relies on __uuidof(CoClassName)
to return the GUID of the CoClass. Instead, code should use the CLSID_xxxx GUIDs generated by TLIBIMP for CoClasses.
That is, you would rewrite the above code as follows:
#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;
}