2011-09-07 41 views
0

我正在将C++代码移植到c#中。有两种结构,如下面的 所述。 //必须是总的180个字节在C#中的memcpy与不同的数据类型

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 

我的代码使用在以下的方式的memcpy。

MAINTENANCE_PARAM maintainanceParam; 
    OCI_PARAM ociParam  

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

据我所知在C#中没有memcpy的代码。那么如何将上面的代码移植到C#中,以便将上述代码移植到 。我是C#的新手。我不太了解C#的 。那么有没有人可以告诉我,我可以如何在C#中实现上述 代码行。我需要将180个字节从一个结构复制到另一个具有不同数据类型的结构对象 在此之前感谢您的任何帮助。 问候, 阿希什

+0

你不能。你是否需要这些结构来连接另一个传统的应用程序/系统/库,或者你是否重新实现了一切? – xanatos

+0

我需要这些结构,因为它:-) – Ashish

回答

3

使用您的结构和StructLayoutAttributeFieldOffsetAttribute这样就可以明确地布置你的字段,然后导入RtlMoveMemory(P/Invoke的)。您可以修改签名以采取任何指针类型(在不安全的上下文中)或使用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