最近遇见了一个很老的COM接口,函数参数声明竟然没有[in] [out]! 当时心里在暗骂这种代码当年怎么通过的code review!
改造这种接口,而同时又不能影响老的接口行为,必须弄清楚如果in out都没有,默认行为应该是什么样的,于是乎写了一个小程序,ATL Service, 然后在其接口定义中故意没加in out:
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(0736591A-734E-4a3d-A1F0-E7D1112EA3AB),
helpstring("IMyTest Interface"),
pointer_default(unique)
]
interface IMyTest : IUnknown
{
HRESULT MyFun(
int iIndex,
BSTR bstrName,
IUnknown** ppIUnknown
);
};
[
uuid(5AA55643-DDC6-49E1-85CF-E7D1112EA3A9),
version(1.0),
]
library ATLProject1Lib
{
importlib("stdole2.tlb");
};
最后查看MIDL编译后生成的ATLProject1_p.c文件如下:
static const ATLProject1_MIDL_PROC_FORMAT_STRING ATLProject1__MIDL_ProcFormatString =
{
0,
{
/* Procedure MyFun */
0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x3 ), /* 3 */
/* 8 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 10 */ NdrFcShort( 0x8 ), /* 8 */
/* 12 */ NdrFcShort( 0x8 ), /* 8 */
/* 14 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */
0x4, /* 4 */
/* 16 */ 0x8, /* 8 */
0x5, /* Ext Flags: new corr desc, srv corr check, */
/* 18 */ NdrFcShort( 0x0 ), /* 0 */
/* 20 */ NdrFcShort( 0x1 ), /* 1 */
/* 22 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter iIndex */
/* 24 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 26 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 28 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter bstrName */
/* 30 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */
/* 32 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 34 */ NdrFcShort( 0x1c ), /* Type Offset=28 */
/* Parameter ppIUnknown */
/* 36 */ NdrFcShort( 0x200b ), /* Flags: must size, must free, in, srv alloc size=8 */
/* 38 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 40 */ NdrFcShort( 0x26 ), /* Type Offset=38 */
/* Return value */
/* 42 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 44 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 46 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
可以看到所有参数类型都是默认为in(比如/* Flags: in, base type, */)!