繁体   English   中英

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

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

我有一个方法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;
}

我有方法MemReadInt32MemReadBool ,...调用MemRead并进行转换

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

现在我想在堆栈而不是堆上分配缓冲区,所以我更改了这一行

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

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

编译器抛出错误,因为堆栈分配的数组不能在声明范围之外公开。 这是有道理的,这可以防止对堆的潜在提升。

但是后来我被迫将转换代码放置在与读取代码相同的方法中。 读取代码将针对每个MemReadInt32MemReadBool 、 ...

如何避免重复ReadMem代码,并且仍然获得堆栈分配?

这是一个非常简单的解决方案,所以我可能会遗漏一些东西,但是为什么不将缓冲区作为参数呢? 然后,您可以在调用函数中堆栈分配一个合适大小的 Span。 否则,我认为没有办法在函数返回后无法访问其堆栈空间(除非通过将指针传递出去并希望数组仍然存在 - 尽管经过一些测试,它似乎从未存在 - 也许是 CLR作为安全预防措施覆盖它?)

暂无
暂无

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

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