我有一个ATL COM组件引发了一些由托管(C#和VB.NET)代码处理的事件。该组件当前由VS2005 VB.NET项目(作为ActiveX控件)使用,并且引发所有事件并且一切正常。IDispatch :: Invoke正在返回E_INVALIDARG
但是,在将一些代码移植到C#时,我注意到除了其中一个事件外,其他所有事件都从未提出。唯一引发的事件不会传回给处理程序。其他人都这样做。
// this function is auto-generated
HRESULT Fire_SomeEvent(VARIANT_BOOL inOriginated, IUserType * inUserType)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[2];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[1] = inOriginated;
pvars[0] = inUserType;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x7, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete[] pvars;
return varResult.scode;
}
Invoke
返回0x80070057 (E_INVALIDARG)
。然而,在VB的土地上,当通过ActiveX包装器使用它时,它可以工作。现在,我无论如何都不是COM向导,我只是不明白。我无法在任何地方找到适用的东西。
我认为这可能与通过UDT有关,但没有;一个几乎相同的版本,IUserType
替换为LONG
也返回E_INVALIDARG
。再次,通过没有参数的单个事件的作品。
托管代码如何使用它的简短示例。没有什么疯狂的。
class Program
{
private ComType _c;
static void Main(string[] args)
{
_c = new ComType();
_c.SomeEvent += _c_SomeEvent;
_c.DoSomethingWhichRaisesSomeEvent();
}
static void _c_SomeEvent(bool b, IUserType udt)
{
// never called
}
}
我通常会花更多时间调试才能到达此处,但我必须尽快拨打电话。我要么必须解决这个问题,要么放弃这个接口并使用另一个接口(这对我而言是次优的)。所以,希望你们中的一些COM专业人士以前遇到过这个问题。
Reintepret_cast代替Qis for IDispatch是错误的。 –
我也会仔细检查distarams的vt值。第一个参数是否应该是IDispatch?我预计指数会按升序排列,而不是下降。 –
“UDT”是一个红色标记,需要在类型库中定义,以便在从VT_RECORD转换后继续存在。 –