Reputation: 181
I have the following C# code: (Updating the code/question) The code and the project are marked as unsafe
private struct MEMORY_BASIC_INFORMATION
{
internal uint BaseAddress;
internal uint AllocationBase;
internal uint AllocationProtect;
internal uint RegionSize;
internal uint State;
internal uint Protect;
internal uint Type;
}
public unsafe static bool CheckForSufficientStack(long bytes)
{
MEMORY_BASIC_INFORMATION stackInfo = new MEMORY_BASIC_INFORMATION();
// originally was
// IntPtr currentAddr = new IntPtr((uint)&stackInfo - 4096);
GCHandle gh = GCHandle.Alloc(stackInfo, GCHandleType.Pinned);
IntPtr p = gh.AddrOfPinnedObject();
//now - this line passes compilation
IntPtr currentAddr = new IntPtr((uint)p - 4096);
// build error in the below line
VirtualQuery(currentAddr, ref stackInfo, sizeof(MEMORY_BASIC_INFORMATION));
return ((uint)currentAddr.ToInt64() - stackInfo.AllocationBase) >
(bytes + STACK_RESERVED_SPACE);
}
and when I compile it I get the error: Cannot take the address of, get the size of, or declare a pointer to a managed type
This is a code I copied and I was actually surprised to know there is '&' in c# but then build failed.
Any idea how to resolve this?
The error is now for the last line when we do a sizeof(MEMORY_BASIC_INFORMATION)
Upvotes: 2
Views: 129
Reputation: 9244
You must "pin" the object in memory first, to make sure that theGC won't move it while you use it:
GCHandle gh = GCHandle.Alloc(stackInfo, GCHandleType.Pinned);
IntPtr p = gh.AddrOfPinnedObject();
Get the size of the struct with:
Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))
Upvotes: 2
Reputation: 181
The original code from here http://joeduffyblog.com/2006/07/15/checking-for-sufficient-stack-space/ passed compilation when I wrote it inside a new class and not inside an existing class I already have... I have no idea why it passed....
Upvotes: 0
Reputation: 156978
In order to make it work you have to indicate you are using unsafe code in C# (since a miscalculation for example could end you up with an invalid address). This is enforced by the unsafe
keyword.
unsafe
{
IntPtr currentAddr = new IntPtr((uint)&stackInfo - 4096);
}
Also make sure your project settings have Unsafe code enabled.
Upvotes: 1