使用C#中的参数打包IDispatch调用(使用DISPPARAMS)

时间:2010-08-02 08:49:32

标签: c# com automation marshalling idispatch

我正在使用Invoke对支持IDispatch的旧COM对象进行后期绑定。这似乎是必要的,因为.NET的Type.GetMethod Type.InvokeMember似乎不适用于这些对象。

以下代码适用于从对象获取属性,调用者将属性名称作为字符串传递,以获取具有后期绑定的属性值。该类在其构造函数中获取一个对象,并将this.idisp(和this.lcid)设置为该对象的接口指针(Critiques welcome!)

public object InvokeGet(string propertyName)
{
    int id = GetDispID(propertyName);
    IntPtr[] pArgErr = default(IntPtr[]);
    object pVarResult;
    System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams = default(System.Runtime.InteropServices.ComTypes.DISPPARAMS);
    System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo = default(System.Runtime.InteropServices.ComTypes.EXCEPINFO);

    Guid guid = new Guid();
    int result = this.idisp.Invoke(id, ref guid, (uint)this.lcid,
                 (ushort)System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_PROPERTYGET,
                 ref pDispParams, out pVarResult, ref pExcepInfo, pArgErr);

    if (result != 0)
    {
        throw new ArgumentException(string.Format("Error invoking property: {0}.  COM error code is {1}", propertyName, result));
    }

    return pVarResult;
}

我现在正在尝试编写等效的setter,即

public void InvokeSet(string propertyName, object newValue)

但是我不知道如何用C#打包Dispatch参数。

即。如何设置结构:

System.Runtime.InteropServices.ComTypes.DISPPARAMS 

我知道我需要从托管对象创建一个非托管变体来编组。有什么建议怎么做?

1 个答案:

答案 0 :(得分:1)

我知道晚会很晚,但是我找到了答案。

// Create the DISPPARAMS struct
var pDispParams= default(System.Runtime.InteropServices.ComTypes.DISPPARAMS);
// Set the number of unnamed parameters
pDispParams.cArgs = 1;

// Marshal a value to a variant
int value = 10;
IntPtr pVariant = Marshal.AllocCoTaskMem(16); // Default VARIANT size
Marshal.GetNativeVariantForObject(value, pVariant);

// Set the unnamed parameter arguments
pDispParams.rgvarg = pVariant;

// Call the IDispatch.Invoke
int result = this.idisp.Invoke(id, ref guid, (uint)this.lcid, 
    (ushort)System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_PROPERTYGET,
    ref pDispParams, out pVarResult, ref pExcepInfo, pArgErr);

我很难弄清楚如何在C#中编组变体。我发现this article本质上回答了我所有的悬而未决的问题,也回答了你的问题。

希望这仍然可以对某人有所帮助。