如何使用COM在.NET和C ++之间传递结构?

时间:2011-03-07 20:57:06

标签: .net com interop struct

我使用以下方法在我的C ++程序中托管.NET库,但不是详尽的列表:

CorBindToRuntimeEx()
GetDefaultDomain()
CreateInstance()
GetIDsOfNames()

最后打电话给Invoke()

这适用于基本类型,枚举,字符串和数组。但是,我无法弄清楚如何传递结构。这是我现在拥有的骨架:

//library.cs  
public class AStruct
{
    public int i1;
    public string s1;
    public double d1;
}  

//...
public AStruct getAStruct();

//interop.cpp  
HRESULT hr = assembly->Invoke (id_getAStruct, ...);

此函数的OUT PARAM返回值为VARIANT,其类型为VT_DISPATCH

当我在调试器中查看retVal.pdispVal时,我可以看到我的struct的内容不在该地址附近。我想使用varIDis.pdispVal->QueryInterface()来访问我的结构,但我不知道IID是什么,也不知道如何发现它。

另外,我没有.NET库的源代码,尽管我可以用Reflector看到它的大部分内容。我正在使用我在.NET中编写的测试库来弄清楚如何继续。

那么,如何使用COM传递和接收.NET和C ++之间的结构?

非常感谢。

1 个答案:

答案 0 :(得分:1)

我不认为你的问题与结构有关。实际上,这里没有涉及结构 - 不是在C#中,也不是在C ++中,也不是COM。 getAStruct方法(某些未指定的类?)返回指向AStruct类实例上的IDispatch接口的指针。

你没有足够的硬信息来正确地做事,所以这就是我接近它的方式......(很多猜测......)

忘记结构。你坚持使用IDispatch *。如果你知道AStruct类的完整定义,或者至少知道它的属性的完整列表以及它们的定义顺序,那么从这个假设开始:第一个属性的DISPID是0x6002000。接下来是0x6002001,依此类推。当然,这不能保证,但你可能很幸运。我忘记了导致DISPID从0x60020000开始的条件,因此可能完全错误。此外,我不认为保证属性的DISPID与源代码中的定义顺序相同。

轻松地移动,在你已经获得的IDispatch *上调用IDispatch :: Invoke,传递猜测的DISPID和wFlags = DISPATCH_PROPERTYGET / PUT。

像我说的那样,很多猜测。但如果我的背靠墙,那就是我开始的地方。