[英]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;
}
我有方法MemReadInt32
, MemReadBool
,...調用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];
編譯器拋出錯誤,因為堆棧分配的數組不能在聲明范圍之外公開。 這是有道理的,這可以防止對堆的潛在提升。
但是后來我被迫將轉換代碼放置在與讀取代碼相同的方法中。 讀取代碼將針對每個MemReadInt32
、 MemReadBool
、 ...
如何避免重復ReadMem
代碼,並且仍然獲得堆棧分配?
這是一個非常簡單的解決方案,所以我可能會遺漏一些東西,但是為什么不將緩沖區作為參數呢? 然后,您可以在調用函數中堆棧分配一個合適大小的 Span。 否則,我認為沒有辦法在函數返回后無法訪問其堆棧空間(除非通過將指針傳遞出去並希望數組仍然存在 - 盡管經過一些測試,它似乎從未存在 - 也許是 CLR作為安全預防措施覆蓋它?)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.