C# 使用VT#u VARIANT+处理COM事件;VT_记录参数

C# 使用VT#u VARIANT+处理COM事件;VT_记录参数,c#,.net,com,activex,com-interop,C#,.net,Com,Activex,Com Interop,我有一个旧的ActiveX DLL,它会引发一些以结构作为参数的事件: HRESULT Fire_OnError( T_ErrorInfo * error_info ) { //forward declare the IID of the UDTVariable structure const IID T_ErrorInfo_IID = { 0xBF5573C3, 0x28DD,

我有一个旧的ActiveX DLL,它会引发一些以结构作为参数的事件:

HRESULT Fire_OnError( T_ErrorInfo * error_info )
{
  //forward declare the IID of the UDTVariable structure
  const IID T_ErrorInfo_IID = { 0xBF5573C3, 
                                0x28DD,
                                0x11DE, {
                                         0xAB,
                                         0xF5, 
                                         0x00,
                                         0x50,
                                         0x56,
                                         0xC0,
                                         0x00,
                                         0x08
                                        }
                              };

  HRESULT hr = S_OK;
  T * pThis = static_cast<T *>(this);
  int cConnections = m_vec.GetSize();

  IRecordInfo *pRI;

  hr = GetRecordInfoFromGuids(LIBID_AxEuroATLib, 
                              AX_VER_MAJOR, 
                              AX_VER_MINOR, 
                              LOCALE_USER_DEFAULT, 
                              T_ErrorInfo_IID, 
                              &pRI);
  CComVariant avarParams[1];
  avarParams[0].vt = VT_RECORD;
  avarParams[0].pvRecord = error_info;
  avarParams[0].pRecInfo = pRI;
  pRI = NULL;

  DISPPARAMS params = { avarParams, NULL, 1, 0 };

  for (int iConnection = 0; iConnection < cConnections; iConnection++)
  {
    pThis->Lock();
    CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
    pThis->Unlock();

    CComQIPtr< IDispatch, &IID_IDispatch > pDispatch( punkConnection );

    if (pDispatch != NULL)
      hr = pDispatch->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
  }

  return hr;
}
但是,当COM调用Invoke()时,会出现两个异常:

A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Impossibile eseguire il mapping del record specificato su una classe di valori gestita.


A first chance exception of type 'System.NotImplementedException' occurred in mscorlib.dll
Additional information: Variant.ToObject cannot handle VT_RECORD
编辑:
T_ErrorInfo定义如下:

typedef 
[ 
    uuid(6C3EB8FD-565E-11E1-B86C-0800200C9A66),
    version(1.0),
]
enum E_ERRORS {
  ....
  errors list
  ....
} E_ERRORS;

typedef 
[ 
    uuid(BF5573C3-28DD-11DE-ABF5-005056C00008), 
    version(1.0),

    helpstring("TErrorInfo structure")
]
struct T_ErrorInfo
{
  E_ERRORS err_no;
  BSTR     description;
  BSTR     routine;
}T_ErrorInfo;
有没有办法“绕过”并解决这个问题


提前谢谢。

VT\U的记录非常脆弱。您正在强制CLR调用GetRecordInfoFromTypeLib()以获取记录描述。它失败,类型为_E_UNSUPFORMAT。当记录包含非自动化类型时,往往会发生这种情况。我们看不出t_ErrorInfo是什么样子,但指针肯定是不允许的。嗨@HansPassant谢谢你的回复。我在我的问题中添加了T_ErrorInfo定义,也许问题在于枚举?
typedef 
[ 
    uuid(6C3EB8FD-565E-11E1-B86C-0800200C9A66),
    version(1.0),
]
enum E_ERRORS {
  ....
  errors list
  ....
} E_ERRORS;

typedef 
[ 
    uuid(BF5573C3-28DD-11DE-ABF5-005056C00008), 
    version(1.0),

    helpstring("TErrorInfo structure")
]
struct T_ErrorInfo
{
  E_ERRORS err_no;
  BSTR     description;
  BSTR     routine;
}T_ErrorInfo;