簡體   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