2016-12-20 8 views
0

管理対象クラスからネイティブ構造体を埋める必要があります。テクニックに従う(1.マネージドバイト配列にマネージドデータをコピーする、2. memcopyを使ってネイティブ構造体を埋め込む)私はこれに対する共通の解決策であることが分かった。 次のコードが機能しない理由は、マネージドクラスをマネージド構造体ではなく使用していることです。私のプロジェクトでは、クラスを管理することが必須条件です。このコードをマネージドクラスを使用して動作させることができますか、またはマネージド構造体に切り替える必要がありますか?管理対象クラスからネイティブ構造体へのコピー

[StructLayout(LayoutKind.Sequential)] 
public class man_s 
    { 
    public man_s() 
    { 
     // (do something which i can't do in a struct!) 
    } 

    // should go into a one-byte native bool 
    [MarshalAs(UnmanagedType.I1)] 
    public bool flag1; 

    public Int32 a; 

    public Int32 b; 
    }; 

...ネイティブCPP構造体:

struct nat_s 
    { 
    public: 
      bool flag1; 
      __int32 a; 
      __int32 b; 
    }; 

...ネイティブ構造体に管理されたデータをコピーしてくださいコード:

この

は、C#のマネージクラスです

// setup some managed data 
man_s^ mng = man_s(); 
    mng->flag1 = true; 
    mng->a = 10; 
    mng->b = 20; 

    nat_s nat; 
    int s = sizeof(nat); 

    // size check is ok! 
    System::Diagnostics::Debug::Assert(sizeof(nat) == System::Runtime::InteropServices::Marshal::SizeOf(mng)); 

    // copy into managed byte array 
    array<byte>^ byteArray = gcnew array<byte>(s); 
    System::Runtime::InteropServices::Marshal::Copy(IntPtr((void*)(&mng)), byteArray, 0, s); 

    // this doesn't bring up the expected results 
    pin_ptr<byte> start = &byteArray[0]; 
    memcpy(&nat, start, s); 

    // does not work either 
    System::Runtime::InteropServices::Marshal::Copy(byteArray, 0, IntPtr((void*)(&nat)), s);enter code here 

答えて

0

Marshal.Copyは、管理対象配列と非管理対象配列の間でデータをコピーするためのものです。これはあなたがここにあるものではありません:管理されたオブジェクトとunmnaged構造体を持っています。そのためには、PtrToStructureStructureToPtrのメソッドが必要です。これらのメソッドは、管理対象オブジェクトと何らかの管理されていないメモリ間のコピーを対象としています。

// Despite the name, man_s is a managed class, not a managed struct. 
// This means it gets the^(which you had correct), 
// but it also means it gets gcnew (which you were missing). 
man_s^ mng = gcnew man_s(); 
nat_s nat; 

// You had this code is correct. 
Debug::Assert(sizeof(nat) == Marshal::SizeOf(mng)); 

// StructureToPtr copies to unmanaged memory. 
// An unmanaged array (i.e., allocated with `malloc` or `new byte[]`) 
// would work, but a pointer to the unmanaged struct will also work just fine. 
// The `false` means "Don't destroy the object that's already at the destination", 
// which I believe does not apply here. 
Marshal::StructureToPtr(mng, &nat, false); 

// You can go the other way as well. 
Marshal::PtrToStructure(&nat, mng); 
// or 
man_s = Marshal::PtrToStructure<man_s>(&nat); 

注:私は現在コンパイラーではありません。 &natIntPtrにキャストする必要があります。

+0

おかげで良い選択 – deafjeff

0

番号AFAIKはできません。あなたは管理されたref classのメモリレイアウトについて何も知らない。内部にvalue typeを割り当てることができます。これをピン止めしてブロック全体としてコピーすることができます。

また、私はあなたのコードを理解していません。 Marshal :: Copyを使用してマネージメモリをコピーします。そして、管理されたクラスをネイティブポインタに変換する際にこれを行います。これを管理対象メモリにコピーし、この管理対象メモリを再度ネイティブメモリにコピーするよりも!どうしてですか?ネイティブポインターとして機能するピンポインターがある場合。

+0

上記のように、管理対象をネイティブにコピーするには、まず管理されたバイト配列にコピーし、次にmemtpyをネイティブ構造体にコピーします。それで全部です。おそらく一歩一歩。私は値の型を使って1ステップ少ない試行をします。とにかくありがとう! – deafjeff

+0

ああ、最後のMarshal :: Copyのコードで「どちらも動作しない」というコメントは、私が知っていることを知っていることを知っているだけでも失敗することがあります。 – deafjeff

+0

..それは、pin_ptrがmemcpyを確立するために標準タイプ(バイト)を必要とするので、あなたは2ステップが必要です。 – deafjeff

関連する問題