简体   繁体   中英

How to use C# stackalloc and keep the same code structure?

I have a method MemRead that reads memory and returns a byte array

[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, ref byte lpBuffer, int dwSize, out int lpNumberOfBytesRead);


public static Span<byte> MemRead(this Process process, IntPtr address, int size)
{
if (process == null)
    throw new ArgumentException("Process is null");

Span<byte> buffer = new byte[size];
bool success = NativeMethods.ReadProcessMemory(process.Handle, address, ref MemoryMarshal.GetReference(buffer), size, out int lpNumberOfBytesRead);

if (!success)
    throw new Exception("ReadProcessMemory failed");

if (lpNumberOfBytesRead < size)
    throw new Exception($"ReadProcessMemory failed : {lpNumberOfBytesRead} bytes read out of {size}");

return buffer;
}

And I have methods MemReadInt32 , MemReadBool , ... that call MemRead and do the conversion

public static int MemReadInt32(this Process process, IntPtr address)
{
    return BitConverter.ToInt32(MemRead(process, address, 4));
}

Now I want to allocate the buffer on the stack instead of the heap so I change this line

Span<byte> buffer = new byte[size];

to

Span<byte> buffer = stackalloc byte[size];

The compiler throws an error because a stack allocated array cannot be exposed outside of the declaration scope. It makes sense this prevents a potential promotion to the heap.

But then I'm forced to place the conversion code in the same method as the reading code. And the reading code will be repeated for each MemReadInt32 , MemReadBool , ...

How can I avoid repeating the ReadMem code, and still get stack allocation ?

This is a very simple solution, so I may be missing something, but why don't you take the buffer as a parameter? You could then stackalloc a Span of the right size in the caller function. Otherwise I don't think there is a way as a function's stack space is not accessible after its return (except by passing a pointer out and hoping that the array is still there - though after some testing it never seemed to be - maybe the CLR overwrites it as a safety precaution?)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM