在非托管c ++中使用size_is的MIDL编组结构数组

时间:2013-04-19 16:44:00

标签: midl

我正在尝试通过COM接口检索结构数组。当结构数为1时,它起作用。当结构数大于1时,只有第一个结构被正确地编组。数组中的其余结构具有垃圾数据。 我的界面如下所示:

typedef struct tagINTOBJINTERFACE
{
    long lObjectId;
    IMyObject* pObj;

} INTOBJINTERFACE;


[
    object,
    uuid(<removed>),
    dual,
    nonextensible,
    helpstring("Interface"),
    pointer_default(unique)
]
interface IMyInterface : IUnknown {

    HRESULT CreateObjects(
        [in] VARIANT* pvDataStream,
        [out]long* Count, 
        [out,size_is(,*Count)] INTOBJINTERFACE** ppStruct
        );
};

我像这样分配结构内存:

long lCountInterfaces = listInterfaces.GetCount();
long lMemSize = lCountInterfaces * sizeof(INTOBJINTERFACE);
INTOBJINTERFACE* pstruct = (INTOBJINTERFACE*) CoTaskMemAlloc( lMemSize );

然后填写数组中每个结构的成员。我可以在调试器中看到所有数组元素的所有成员都已正确分配。 在填充结构后,我指定“* ppStruct = pstruct”来传递数组。 我还可以看到out参数“* Count”已正确设置为正确的元素数。

为什么这不起作用?

2 个答案:

答案 0 :(得分:5)

原因: 您的应用程序使用Windows中的通用编组器进行编组。 通用编组器从类型库(* .tlb)中读取元数据 生成的typelib不支持size_is。

TODO: 您应该使用Visual Studio生成的Proxy / Stub dll(... PS项目)。   - 构建代理/存根DLL   - 调用“regsvr32”   - 从服务器中删除“TypeLib = s”{????? -...- ????}'“条目”* .rgs“    文件

答案 1 :(得分:0)

除了Joerg的答案是不可能使用size_is之外,这里还有可能:SAFEARRAY

关键字:UDT的Safearray

说明和示例为here

简短摘要:

  1. 使用GUID定义结构。
  2. 使用类型库创建描述您的结构的IRecordInfo类型的对象。
  3. 使用SafeArrayCreateEx创建类型SAFEARRAY的{​​{1}}。
  4. 用数据填充它。
  5. 在另一侧检索。