[英]unsigned char * - Equivalent C#
我正在將一個庫從C ++移植到C#,但遇到了一個我不確定如何解決的場景,這涉及將unsigned char *
轉換為unsigned int *
。
C ++
unsigned int c4;
unsigned int c2;
unsigned int h4;
int pos(unsigned char *p)
{
c4 = *(reinterpret_cast<unsigned int *>(p - 4));
c2 = *(reinterpret_cast<unsigned short *>(p - 2));
h4 = ((c4 >> 11) ^ c4) & (N4 - 1);
if ((tab4[h4][0] != 0) && (tab4[h4][1] == c4))
{
c = 256;
return (tab4[h4][0]);
}
c = 257;
return (tab2[c2]);
}
C#(這是錯的):
public uint pos(byte p)
{
c4 = (uint)(p - 4);
c2 = (ushort)(p - 2);
h4 = ((c4 >> 11) ^ c4) & (1 << 20 - 1);
if ((tab4[h4, 0] != 0) && (tab4[h4, 1] == c4)) {
c = 256;
return (tab4[h4, 0]);
}
c = 257;
return (tab2[c2]);
}
我相信在C#示例中,您可以將byte p
更改為byte[]
但是當將byte[]
轉換為單個uint值時我無能為力。
另外,有人可以向我解釋一下,為什么要將unsigned char *
轉換為unsigned int *
? 它有什么用途?
任何幫助/推動方向都將非常有用。
有問題的線的翻譯將是:
int pos(byte[] a, int offset)
{
// Read the four bytes immediately preceding offset
c4 = BitConverter.ToUInt32(a, offset - 4);
// Read the two bytes immediately preceding offset
c2 = BitConverter.ToUInt16(a, offset - 2);
並從x = pos(&buf[i])
(即使在C ++中與x = pos(buf + i)
相同x = pos(&buf[i])
更改調用
x = pos(buf, i);
一個重要的注意事項是現有的C ++代碼是錯誤的,因為它違反了嚴格的別名規則。
在C#中實現類似功能不需要涉及在逐個語句的基礎上復制C版本的代碼,尤其是在原始程序使用指針時。
當我們假設一個int
為32位的體系結構時,你可以像這樣簡化C#版本:
uint[] tab2;
uint[,] tab4;
ushort c;
public uint pos(uint c4)
{
var h4 = ((c4 >> 11) ^ c4) & (1 << 20 - 1);
if ((tab4[h4, 0] != 0) && (tab4[h4, 1] == c4))
{
c = 256;
return (tab4[h4, 0]);
}
else
{
c = 257;
var c2 = (c4 >> 16) & 0xffff; // HIWORD
return (tab2[c2]);
}
}
這種簡化是可能的,因為c4和c2重疊:c2是c4的高位字,只有當tab4
中的查找不匹配時才需要。
(標識符N4
存在於原始代碼中,但在您自己的翻譯中由表達式1 << 20替換)。
調用代碼必須循環遍歷int數組,根據注釋是可能的。 雖然原始C ++代碼從偏移量4開始並回顧,但C#等價物將從偏移量0開始,這似乎是更自然的事情。
在C ++代碼中,您發送指向char的指針,但通常C#不使用這種方式使用內存,您需要數組而不是指針。
但您可以使用unsafe
關鍵字直接處理內存。 https://msdn.microsoft.com/en-us/library/chfa2zb8.aspx
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.