4

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

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

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 

我知道我需要从托管对象创建一个非托管变体来编组。任何建议如何做到这一点?

4

1 回答 1

2

我知道,聚会很晚,但我为你找到了答案。

// 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# 中编组变体。我发现这篇文章基本上回答了我所有未解决的问题,也回答了你的问题。

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

于 2018-10-09T18:01:33.880 回答