You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#与Delphi代码结果不一致:char数组地址异或输出差异

Why Delphi and C# Give Different Results When Converting Char Array to Integer?

Let's break down exactly why you're seeing inconsistent results between Delphi and C# here—this all boils down to differences in character memory layout and how each language handles pointer conversions.

Core Background

First, let's clarify the key type differences that are causing the mismatch:

  • Delphi:
    • By default (pre-2009, or if explicitly using AnsiChar), a Char is a 1-byte ASCII character.
    • Longint is a 4-byte signed integer, and on x86 systems, Delphi uses little-endian byte ordering (lower bytes stored at lower memory addresses).
  • C#:
    • A char is always a 2-byte UTF-16 character (even for ASCII values—high byte is 0 for standard ASCII chars).
    • int (equivalent to Delphi's Longint) is also a 4-byte signed integer with little-endian ordering, but the char array's memory footprint is completely different.

Step-by-Step Analysis

First, let's list the ASCII values of your input characters:

  • . = ASCII 46 (hex 0x2E)
  • STX = ASCII 2 (hex 0x02)
  • NUL = ASCII 0 (hex 0x00)

Delphi's Calculation (Result: 558)

Your Delphi code is casting a pointer to the 4-element AnsiChar array directly to a PLongint and dereferencing it. Here's what that looks like in memory:

Memory Address (Low → High)Byte Value
0x000x2E
0x010x02
0x020x00
0x030x00

With little-endian ordering, this 4-byte block translates to the integer:
0x0000022E = (0x02 * 256) + 0x2E = 512 + 46 = 558
Which matches your Delphi result.

C#'s Calculation (Result: 11783192)

C#'s char array uses 2 bytes per character, so your 4-char array takes up 8 bytes of memory. The memory layout looks like this (each char is stored as a 2-byte UTF-16 value):

Memory Address (Low → High)Byte ValueCorresponding Char
0x000x2E. (low byte)
0x010x00. (high byte)
0x020x02STX (low byte)
0x030x00STX (high byte)
0x040x00NUL (low byte)
0x050x00NUL (high byte)
0x060x00NUL (low byte)
0x070x00NUL (high byte)

When you perform an address XOR with Posit=5 and read the resulting 4-byte block, you're picking up a different set of bytes than Delphi. The value 11783192 translates to hex 0x00B3022E—this suggests you're reading a shifted segment of the UTF-16 char array's memory, which doesn't align with Delphi's 1-byte-per-character layout.

Fixing the Mismatch

To get C# to match Delphi's result, you need to replicate Delphi's 1-byte-per-character memory layout:

  1. Use a byte array instead of a char array (since your source is an ASCII file):

    // Match the ASCII byte values directly
    byte[] tmPByte = new byte[] { 46, 2, 0, 0 };
    int inLong = BitConverter.ToInt32(tmPByte, 0);
    // Result: 558 (matches Delphi)
    

    BitConverter.ToInt32 uses little-endian ordering by default on x86 systems, which aligns with Delphi's behavior.

  2. If you must start with a char array, convert each char to its ASCII byte first:

    char[] tmPChar = new char[] { '.', '\x02', '\x00', '\x00' };
    byte[] tmPByte = tmPChar.Select(c => (byte)c).ToArray();
    int inLong = BitConverter.ToInt32(tmPByte, 0);
    

Key Takeaway

The root cause is C#'s 2-byte UTF-16 chars vs. Delphi's 1-byte AnsiChars—this creates completely different memory layouts for the same logical input. Add in pointer operations like address XOR, and you end up reading entirely different memory segments, leading to the mismatched integer values.

内容的提问来源于stack exchange,提问作者Adonis Pso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:32:22