2011-09-08 10 views
3

私は、ネイティブコードと共有されるデータの構造体(実際にはクラス、参照型です)との間で、IntPtrをマーシャリングすることを抽象化しようとしています。私は希望++Cの引数を使用してC#の実装を隠す

using (Shared_s data = new Toolbox.NativeStruct<DataStruct>(myIntPtr).Data) 
{ 
    data.someMember = someValue; 
} 

Cで

EditStruct(DataStruct, myIntPtr) 
{ 
    data.someMember = someValue; 
} 

にこれを変更するにはいくつかの方法:

class NativeStruct<StructType> : IDisposable 
{ 
    public NativeStruct() 
    { 
     _DataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StructType))); 
     Marshal.PtrToStructure(_DataPtr, _Data); 
    } 
    public NativeStruct(IntPtr dataPtr) 
    { 
     _DataPtr = dataPtr; 
     Marshal.PtrToStructure(_DataPtr, _Data); 
    } 

    void IDisposable.Dispose() 
    { 
     Marshal.StructureToPtr(_Data, _DataPtr, true); 
    } 

    public StructType Data { get { return _Data; } } 

    IntPtr _DataPtr; 
    public StructType _Data; 
} 

が暗黙的にこのコードを作るためにとにかくあり:

私はこのヘルパークラスを持っていますマクロを使用しました

あなたがここに行うことができます
#define EditStruct(StructType, IntPtr) using \ 
(Shared_s data = new Toolbox.NativeStruct<StructType>(IntPtr).data) 

答えて

6

最も近いものは、使用ラムダ式である:EditStruct()

EditStruct<DataStruct>(myIntPtr, data => 
{ 
    data.someMember = someValue; 
}); 

定義:

void EditStruct<TStruct>(IntPtr dataPtr, Action<TStruct> action) 
    where TStruct : struct 
{ 
    using (var s = new Toolbox.NativeStruct<TStruct>(dataPtr)) 
    { 
    action(s.Data); 
    } 
} 
+0

よりも良く見えますしかし、私はどのようにして実装するのか分かりません。 –

+0

それは実装です。 'data => {...}'はメソッドのデリゲートに変換され、 'EditStruct()'では 'action(data)'と呼ばれます。 –

+0

@ Xaade私はこの道を一度 "行った"。私は*大部分のケースでバニラに戻しました。構文上、これはネストされたコードIMOHOの悪夢です。 –

0

C#2.0バージョン:

EditStruct<DataStruct>(myIntPtr, delegate(DataStruct data) 
{ 
    data.someMember = someValue; 
}); 

void EditStruct<TStruct(IntPtr dataPtr, Action<StructType> action) where TStruct : struct 
{ 
    using (Toolbox.NativeStruct<StructType> s = new Toolbox.NativeStruct<StructType>(dataPtr)) 
    { 
     action(s.Data); 
    } 
} 
関連する問題