Я использую Invoke для позднего связывания с устаревшими COM-объектами, которые поддерживают IDispatch. Это кажется необходимым, так как .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;
}
Я сейчас пытаюсь написать сеттерный эквивалент, т.е.
public void InvokeSet(string propertyName, object newValue)
однако я не уверен, как упаковать параметры Dispatch с помощью C #.
т.е.. как настроить структуру:
System.Runtime.InteropServices.ComTypes.DISPPARAMS
Я понимаю, что мне нужно создать неуправляемый вариант от управляемого объекта до маршала. Любые предложения, как это сделать?