我正在为第三方非托管库编写C ++ / CLI(VS2010)中的托管包装器。在代码中,我有一个如下所示的方法:
if(oldState != _state && UnitStateChanged != nullptr)
UnitStateChanged(this, gcnew UnitStateChangedEventArgs(oldState, _state));
“nullptr”会生成以下错误:
错误C2446:'!=':没有从'int'转换为'UnitStateChangedEventHandler ^'
编译器似乎将“nullptr”用作“int”,即使是在这样简单的事情上:
Object^ temp = nullptr;
我读过的所有东西都表明编译器会自己解决它,但事实并非如此。是否有我缺少的设置(/ clr或#pragma托管除外)?
答案 0 :(得分:3)
没有C ++ 11编译器的人写了
#define nullptr (0)
头文件中的某个地方?
(通常的宏是#define NULL (0)
)
当然,这是禁止的。
答案 1 :(得分:2)
看起来你正在尝试解雇一个事件。
在C#中,有一个标准习惯用于触发事件,同时防止空引用异常和多线程修改:
// C#
EventHandler handler = this.MyEvent;
if(handler != null)
handler(this, new EventArgs(foo));
看起来你正试图在C ++ / CLI中重新创建它,但这是不必要的。在C ++ / CLI中,一个事件将发出三个“内部方法”(它们的正确名称是什么?),称为add
,remove
和raise
。在C#中,它只创建add
和remove
,没有显式加注,这就是我们必须反复编写该代码块的原因。
这是在C ++ / CLI中定义的事件,以及.NET Reflector在反编译时看到的内容:
// C++/CLI:
public ref class Test
{
public:
event EventHandler^ MyEvent;
};
// Decompiled to C#:
public class Test
{
// Fields
private EventHandler <backing_store>MyEvent;
// Events
public event EventHandler MyEvent
{
[MethodImpl(MethodImplOptions.Synchronized)] add
{
this.<backing_store>MyEvent = (EventHandler) Delegate.Combine(this.<backing_store>MyEvent, value);
}
[MethodImpl(MethodImplOptions.Synchronized)] remove
{
this.<backing_store>MyEvent = (EventHandler) Delegate.Remove(this.<backing_store>MyEvent, value);
}
raise
{
EventHandler <tmp> = null;
<tmp> = this.<backing_store>MyEvent;
if (<tmp> != null)
{
<tmp>(value0, value1);
}
}
}
}
raise
内部方法正在为您执行空检查,因此您可以跳过此操作,只需触发事件而不进行检查。
if(oldState != _state)
this->UnitStateChanged(this, gcnew UnitStateChangedEventArgs(oldState, _state));