最近遇見了一個很老的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, */)!