2

サードパーティのアンマネージド ライブラリ用に 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 managed 以外)?

4

2 に答える 2

3

C++11コンパイラを持たない人が書いた

#define nullptr (0)

ヘッダーファイルのどこか?

(通常のマクロは#define NULL (0)


もちろん、これは禁止されています。

標準セクション17.6.4.3.1、マクロ名としてキーワードを使用することは禁止されています C ++ 11キーワードのリスト(標準の表4)

于 2012-06-25T20:58:59.527 に答える
2

イベントを発生させようとしているようです。

C# には、null 参照例外とマルチスレッド変更から保護しながらイベントを発生させるための標準的なイディオムがあります。

// C#
EventHandler handler = this.MyEvent;
if(handler != null)
    handler(this, new EventArgs(foo));

C++/CLI でそれを再作成しようとしているようですが、不要です。C++/CLI では、イベントはaddremove、 と呼ばれる 3 つの「内部メソッド」 (それが適切な名前ですか?) を発行しますraise。C# では、明示的なレイズを作成するだけで、明示的な昇格はありません。そのため、そのコード ブロックを何度も記述しなければなりませんaddremove

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);
            }
        }
    }
}

内部メソッドが null チェックを行っているraiseため、それをスキップして、チェックせずにイベントを発生させることができます。

if(oldState != _state)
    this->UnitStateChanged(this, gcnew UnitStateChangedEventArgs(oldState, _state));
于 2012-06-25T21:37:05.203 に答える