我有一个ATL组件,它引发一些由托管(C#和VB.NET)代码处理的事件。该组件目前由VS2005 VB.NET项目(作为ActiveX控件)使用,所有事件都会引发,并且一切都正常。
但是,在将部分代码移植到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
}
}我通常会花更多的时间调试,然后才会到达这里,但我必须在这里打个电话。我要么修复这个问题,要么放弃这个接口,使用另一个(这对我的目的来说不是最优的)。所以,希望你们中的一些专业人士以前也遇到过这种情况。
发布于 2014-07-02 14:30:27
在dispparam变体中反复检查您的vt值;许多IDispatch实现都非常详细地列出了所有的内容。
https://stackoverflow.com/questions/24502457
复制相似问题