2011-09-07 29 views
0

私はC++コードをC#に移植しています。以下のように2つの構造体があります。 は//私のコードは次のような方法でのmemcpyを使用して180バイトmemcpy in C#で異なるデータ型

typedef struct MAINTENANCE_PARAM` 
{ 
    BYTE bCommand; 
    BYTE bSubCommand; 
    USHORT usDataLength; 
    union // Must be no larger than 176 bytes 
    { 
     MyStruct1 myStruct1; 
       MyStruct2 myStruct2; 
     BYTE bDummy[176]; 
    } data; 
} MAINTENANCE_PARAM; 

typedef struct _OCI_PARAM { 
    SHORT sType;   // Size: 2 
    LONG lValue;   // 4 
    SHORT sScale;   // 2 
    LONG lValueTabIdx; // 4 
} OCI_PARAM[OCI_MAXPARAM]; //Size: OCI_MAXPARAM = 15 // 15 * 12 = 180 

の合計でなければなりません。

MAINTENANCE_PARAM maintainanceParam; 
    OCI_PARAM ociParam  

    // Copy recieved structure to correct format 
    memcpy((void*)& maintainanceParam, (void*) ociParam, sizeof(OCI_PARAM)); 

私が知っているように、memcpyのコードはC#にはありません。だから、私はどのように 上記のコードをC#に移植することができます。私はC#の初心者です。私は のC#についてはあまり知らない。だから誰でも私はどのように正確に上記の コード行を実装することができます私に教えることができますC#で。ある構造から別の構造体に異なるデータ型の180バイトをコピーする必要があります アドバンスで助けていただきありがとうございます。あなたはRtlMoveMemory(P /呼び出し)をインポートし、明示的に自分のフィールドをレイアウトすることができるよう よろしく、 アシシュ

+0

できません。別の従来のアプリケーション/システム/ライブラリに接続するためにこれらの構造が必要か、すべてを再実装していますか? – xanatos

+0

私はこれらの構造がそのまま必要です:-) – Ashish

答えて

3

は、あなたの構造体のためのStructLayoutAttributeFieldOffsetAttributeを使用してください。任意のポインタ型(安全でないコンテキスト)を使用するようにシグネチャを変更するか、PInvoke.netで標準シグネチャを使用することができます。

unsafe class Program { 

    [System.Runtime.InteropServices.DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)] 
    private static extern void MoveMemory(void* dest, void* src, int size); 

    static void Main(string[] args) { 

     Maintenance_Param p1 = new Maintenance_Param(); 
     p1.bCommand = 2; 
     p1.bSubCommand = 3; 
     p1.usDataLength = 3; 
     p1.myStruct1 = new MyStruct1(); 

     Maintenance_Param p2 = new Maintenance_Param(); 
     MoveMemory(&p2, &p1, sizeof(Maintenance_Param)); 
    } 
} 

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)] 
public struct Maintenance_Param { 

    // fields should be private and be accessed over properties ... 
    [System.Runtime.InteropServices.FieldOffset(0)] 
    public byte bCommand; 
    [System.Runtime.InteropServices.FieldOffset(1)] 
    public byte bSubCommand; 
    [System.Runtime.InteropServices.FieldOffset(2)] 
    public ushort usDataLength; 
    [System.Runtime.InteropServices.FieldOffset(4)] 
    public MyStruct1 myStruct1; 
    [System.Runtime.InteropServices.FieldOffset(4)] 
    public MyStruct2 myStruct2; 
} 

public struct MyStruct1 { 
    int value; 
} 

public struct MyStruct2 { 
    int value; 
} 
+0

詳細な投稿のためにマリオに感謝します。フィールドオフセットを使用してメモリを制御し、CでUnionを複製しましたが、これらの場合にはDllimportを使用したくありません。 pInvoke以外のC#でもっと良い解決策がありますか? – Ashish

+0

@Ashish - リンクを見てください。6opucは – MaLio

1

MemCpyは.NETに存在します! OpCodes.Cpblkをグーグルで試してみてください。ここに例があります:http://www.abstractpath.com/weblog/2009/04/memcpy-in-c.html

+0

の下に投稿して、x86でベンチマークしてみてください。そして、あなたが64ビットのみであるか、少なくともx86上の何かにプローブしてフォールバックするつもりでない限り、それを使用しないでください。興味深い! –

+0

ベンチマークはありますか? – 6opuc

+0

http://code4k.blogspot.ru/2010/10/high-performance-memcpy-gotchas-in-c.html – 6opuc

関連する問題