将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:
stis an array ofuint64_t(8-byte unsigned integers). In C, an array name decays to a pointer to its first element, sostpoints to the start of a 200-byte memory block (25 * 8 bytes).(uint8_t *)stcasts that pointer to auint8_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 originaluint64_tarray.[Length]indexes into this byte-level pointer: it refers to theLength-th byte (0-indexed) starting from the start ofst. We set that byte to0x01.
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 + 1shifts the byte pointer to the position immediately after the0x01we just set.memsetfills all bytes starting at this position with0x00, for a total of128 - Length - 1bytes. This ensures the first 128 bytes ofstare padded with zeros after the initial0x01marker.
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 usingBuffer.BlockCopy, but the loop works perfectly here. - We renamed
Lengthtolengthto follow C# naming conventions (camelCase for parameters).
内容的提问来源于stack exchange,提问作者scaw.dev
相关产品推荐
相关产品推荐

