简体   繁体   English

如何使用 C# stackalloc 并保持相同的代码结构?

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

I have a method MemRead that reads memory and returns a byte array我有一个方法MemRead读取内存并返回一个字节数组

[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我有方法MemReadInt32MemReadBool ,...调用MemRead并进行转换

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 , ...读取代码将针对每个MemReadInt32MemReadBool 、 ...

How can I avoid repeating the ReadMem code, and still get stack allocation ?如何避免重复ReadMem代码,并且仍然获得堆栈分配?

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.然后,您可以在调用函数中堆栈分配一个合适大小的 Span。 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?)否则,我认为没有办法在函数返回后无法访问其堆栈空间(除非通过将指针传递出去并希望数组仍然存在 - 尽管经过一些测试,它似乎从未存在 - 也许是 CLR作为安全预防措施覆盖它?)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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