如何分配的byte []在C#中的指针 [英] How to assign byte[] as a pointer in C#
问题描述
我有生成基于任何packet.The问题的内容的CRC校验字节是在C ++翻译功能到C#的函数
I have a function that generates a CRC check byte based on the content of any packet.The problem is in translating the function from C++ to C#
C ++代码:
unsigned char GenerateCheckByte( char* packet, int length, unsigned long seed )
{
if( !packet ) return 0;
unsigned long checksum = 0xFFFFFFFF;
length &= 0x7FFF;
char* ptr = packet;
unsigned long moddedseed = seed << 8;
for( int i = 0; i < length; i++ )
checksum = ( checksum >> 8 ) ^ table[moddedseed + ( ( *(ptr++) ^ checksum ) & 0xFF )];
unsigned char result = ( (checksum>>24)&0xFF ) + ( (checksum>>8)&0xFF ) + ( (checksum>>16)&0xFF ) + ( checksum&0xFF );
return result;
}
的
的char *(数据包)也可以被定义为LPBYTE,这个想法是所分配的值*数据包分配到* PTR,当你看到* PTR increases.Meaning一个字节数组中,并通过增加它转到下一个字节指针的值传递的。
the char*(packet) can also be defined as LPBYTE,the idea is that the value assigned to *packet is assigned to *ptr and as you see *ptr increases.Meaning a byte array is passed in and by increasing the value of the pointer it goes to the next byte.
我试着做它在C#和失败了很多times.After一些艰苦的工作我想通了一些代码,但我不能执行它:
I tried to do it in C# and failed many times.After some hard work I figured out some code,but i can't execute it :?
C#代码
public static unsafe byte GenerateCheckByte(byte *packet, int length, UInt32 seed )
{
if (*packet == 0)
return 0;
UInt32 checksum = 0xFFFFFFFF;
length &= 0x7FFF;
byte *ptr = packet;
UInt32 moddedseed = seed << 8;
for (int i = 0; i < length; i++)
checksum = ( checksum >> 8 ) ^ Table.table[moddedseed + ( ( *(ptr++) ^ checksum ) & 0xFF )];
byte result = (byte)(( (checksum>>24)&0xFF ) + ( (checksum>>8)&0xFF ) + ( (checksum>>16)&0xFF ) + ( checksum&0xFF ));
return result;
}
它看起来并不那么糟糕,但我不能把它叫做
It doesn't look that bad,but I can't call it
unsafe
{
packetBuffer[5] = Functions.GenerateCheckByte(&packetBuffer[0], 18, packet.seedCRC);
}
错误:你只能采取不固定的表达地址的内部固定语句初始化
error: "You can only take the address of an unfixed expression inside of a fixed statement initializer"
请注意
在C ++和C#应用程序packetbuffer为byte [] packetBuffer =新的字节[18];
packetbuffer in both C++ and C# application is byte[] packetBuffer = new byte[18];
推荐答案
您可以让该方法接受一个字节数组:
You could make the method accept a byte array:
public static unsafe byte GenerateCheckByte(byte[] packetArray, int length, UInt32 seed)
{
fixed(byte *packet = packetArray)
{
... etc
}
}
这是更好地保持不安全的东西隐藏起来,尽可能落后管理接口
It's better to keep the unsafe stuff hidden away as much as possible behind managed interfaces.
然后调用它会很容易。
packetBuffer[5] = Functions.GenerateCheckByte(packetBuffer, 18, ...
在事实上,这将是最好编写 GenerateCheckByte
反正阵列上运行,而不是钻研<, code>不安全技巧:
In fact, it would be better to write GenerateCheckByte
to operate on an array anyway, instead of delving into unsafe
techniques:
public static unsafe byte GenerateCheckByte(byte[] packet, int length, UInt32 seed )
{
if (packet == null)
throw new ArgumentNullException("packet"); // the right way in C#
UInt32 checksum = 0xFFFFFFFF;
length &= 0x7FFF;
UInt32 moddedseed = seed << 8;
for (int i = 0; i < length; i++)
checksum = ( checksum >> 8 ) ^ Table.table[moddedseed + ( ( packet[i] ^ checksum ) & 0xFF )];
byte result = (byte)(( (checksum>>24)&0xFF ) + ( (checksum>>8)&0xFF ) + ( (checksum>>16)&0xFF ) + ( checksum&0xFF ));
return result;
}
写最简单,最安全的实现就可以了,用指针只一塌糊涂,如果你发现分析的一个瓶颈。
Write the simplest, safest implementation you can, and only mess with pointers if you find a bottleneck in profiling.
您刚刚翻译了很多现有的C / C ++到C#的?有小点,这样做,除非你从它那里得到一些新的安全性/可维护性。 :)
Are you just translating a lot of existing C/C++ into C#? There's little point doing that unless you get some new safety/maintainability from it. :)
这篇关于如何分配的byte []在C#中的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!