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

将C代码转为C#时遇(uint8_t*)指针转换问题求助

Understanding the C Pointer Logic & C# Conversion

Let's break down the confusing C code lines first, then walk through the correct C# conversion.

What's Happening in the C Code?

1. ((uint8_t *)st)[Length] = 0x01;

Let's unpack this step by step:

  • st is an array of uint64_t (8-byte unsigned integers). In C, an array name decays to a pointer to its first element, so st points to the start of a 200-byte memory block (25 * 8 bytes).
  • (uint8_t *)st casts that pointer to a uint8_t* (pointer to 1-byte unsigned integers). This lets us access the memory block one byte at a time, instead of the 8-byte chunks dictated by the original uint64_t array.
  • [Length] indexes into this byte-level pointer: it refers to the Length-th byte (0-indexed) starting from the start of st. We set that byte to 0x01.

For example, if Length is 10, we're setting the 10th byte in the st memory block to 0x01—this byte might sit in the middle of one of the uint64_t elements in the array.

2. memset(((uint8_t *)st) + Length + 1, 0x00, 128 - Length - 1);

This is a byte-level memory fill operation:

  • ((uint8_t *)st) + Length + 1 shifts the byte pointer to the position immediately after the 0x01 we just set.
  • memset fills all bytes starting at this position with 0x00, for a total of 128 - Length - 1 bytes. This ensures the first 128 bytes of st are padded with zeros after the initial 0x01 marker.

C# Conversion (Safe, No Unsafe Code)

In C#, we avoid raw pointers by default, but we can use the Buffer class to perform byte-level operations on value-type arrays like ulong[]. Here's the corrected code with explanations:

private void Foo(ref ulong[] output, ref ulong[] input, uint length)
{
    ulong[] st = new ulong[25];
    // Copy first 'length' bytes from input to st (matches C's memcpy)
    Buffer.BlockCopy(input, 0, st, 0, (int)length);

    // Equivalent to ((uint8_t *)st)[length] = 0x01;
    // Set the 'length'-th byte in st's memory to 0x01
    Buffer.SetByte(st, (int)length, 0x01);

    // Equivalent to memset(((uint8_t *)st) + length + 1, 0x00, 128 - length - 1);
    int startFillByte = (int)length + 1;
    int fillByteCount = 128 - (int)length - 1;
    for (int i = 0; i < fillByteCount; i++)
    {
        Buffer.SetByte(st, startFillByte + i, 0x00);
    }

    // Zero out elements 16 to 24 (matches original C loop)
    for (int i = 16; i < 25; ++i)
    {
        st[i] = 0x00U;
    }

    // Set the last padding bit (matches original C code)
    st[16] = 0x8000000000000000U;

    bar(st); // Assuming bar is implemented to accept ulong[] in C#

    // Copy first 200 bytes (25 ulongs) from st to output
    Buffer.BlockCopy(st, 0, output, 0, 200);
}

Key Notes on the C# Code:

  • Buffer.SetByte(array, byteIndex, value) lets us directly modify a specific byte in the memory of a value-type array, mimicking the byte-level pointer access in C without unsafe code.
  • The zero-fill loop is straightforward for this use case. For larger fill lengths, you could optimize by creating a temporary byte[] of zeros and using Buffer.BlockCopy, but the loop works perfectly here.
  • We renamed Length to length to follow C# naming conventions (camelCase for parameters).

内容的提问来源于stack exchange,提问作者scaw.dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:33:04