Не могу получить тот же результат, что и код Delphi, после того как я исключил ИЛИ адрес массива символов в C # - PullRequest
0 голосов
/ 19 марта 2019

Параметры: InLong = 0, Posit = 5 и из файла ASCII TmPChar {., STX, NUL, NUL}

Код Delphi

Procedure TForm1.GetLongFromBuf(Var InLong : Longint; Posit : Integer; ZRepB : ZrepBuf);
Var
  TmpPChar     : Array[0..3] Of Char;
  PLong        : ^Longint;
  I            : Byte;
Begin
For I:= 0 To 3 Do
   TmpPChar[I] := ZRepB[Posit+I];
PLong := @TmpPChar;
InLong := PLong^;
End;

Выходы: TmPChar {'.', # 2, # 0, # 0}, PLong = 13F54C, InLong = 558

код C #

unsafe static long GetLongFromBuf(long InLong, int Posit, char[] ZRepB){
 long* Plong;
 char[] TmpPChar = new char[4];
 for (byte i = 0; i < TmpPChar.Length; i++){
    TmpPChar[i] = ZRepB[(Posit-1) + (i)];
 }
 fixed(char* ch = TmpPChar){
  PLong = (long*)&ch;
  InLong ^= (long)PLong;
 }
 return InLong;
}

Выходы: TmPChar {'.', '\ U0002', '\ 0', '0'}, PLong = 0x0000000000b3cc18, InLong = 11783192

1 Ответ

2 голосов
/ 19 марта 2019

Похоже, что вы используете этот код Delphi, не понимая, что он делает.Исходя из ваших результатов, мы можем заключить, что вы используете версию Delphi до Unicode (т.е. D2007 или более раннюю).Также можно предположить, что ZrepBuf определяет массив байтов или [Ansi] Char.Затем метод работает следующим образом:

For I:= 0 To 3 Do
  TmpPChar[I] := ZRepB[Posit+I];  /* Copy four sequential bytes to TmpPChar array */
PLong := @TmpPChar;               /* Take a pointer to the head of the array */ 
InLong := PLong^;                 /* Dereference the pointer, interpreting as a 32-bit int */

Это код для преобразования четырех байтов в 32-разрядное целое число.В Delphi тип LongInt является псевдонимом для 32-битного типа integer, эквивалентного типу int в C #, а не long.В коде Delphi оператор XOR не используется.В PLong^ оператор ^ является операцией разыменования.

В C # вы можете полностью избежать кода unsafe и просто выполнить это преобразование, используя класс BitConverter:

 byte[] b = new byte[4] { 0x2E, 0x02, 0x00, 0x00 }; 
 int result = BitConverter.ToInt32(b, 0);  // result == 558

Здесь я определил входной массив как byte[], поскольку char в C # (и в Delphi 2009 или новее) - это 16-битный тип (два байта) для хранения символов Unicode,Данные, которые вы читаете, зашифрованы ANSI - я предполагаю, что вы понимаете, как читать ваш текстовый файл в байтовый массив.

Кстати, в более современном Delphi вы могли бы также переписать код указателя выше, чтобы использовать егокласс TEncoding для выполнения этой функции , как описано здесь аналогично классу BitConverter в C #.

...