I'm converting some code from C++ to C#, and I need some insight on how to deal with lines like these:
PDWORD rgb32_data = (PDWORD) malloc(640*480*4);
From what I understand, the PDWORD
type represents an unsigned integer (32bit). What would be a good C# strategy to implement a similar structure?
EDIT: I figured out that I need to use an IntPtr to replace the PDWORD, but the IntPtr would hold a single value as opposed to many values as in an array. Any C# suggestions?
EDIT2: Uint[]s don't work for me - unfortunately, the only way I can make the program compile, with all its dependencies, is when I enter an IntPtr as a the argument, not an IntPtr开发者_运维百科[].
Thanks.
EDIT - I've marked the solution, in addition I needed to do the following:
Since I needed an IntPtr cast, I added this code
IntPtr rgb32_ptr;
GCHandle handle = GCHandle.Alloc(rgb32_data, GCHandleType.Pinned);
try
{
rgb32_ptr = handle.AddrOfPinnedObject();
}
finally
{
if (handle.IsAllocated)
{
handle.Free();
}
}
to get an IntPtr to the same.
According to MSDN, PDWORD
is defined as:
typedef DWORD* PDWORD;
So it's a pointer to a DWORD
, which MSDN also says is an unsigned 32-bit integer - in other words, a uint
.
Note that your line of C++ code allocates memory for an array of 640 * 480 = 307,200 DWORD
s.
You could translate this directly as:
uint[] rgb32_data = new uint[640 * 480];
But the code might really want to use it as just a series of bytes in memory, so you might instead want to use a byte array
byte[] rgb32_data = new byte[640 * 480 * 4];
and use the methods in the BitConverter class (especially the ToInt32()
method) if you think that is closer to how the original program handles the data.
You can use unsafe pointers and Marshal.AllocHGlobal()
Program()
{
unsafe
{
IntPtr ptr = Marshal.AllocHGlobal(640 * 480 * 4);
uint* ptr2 = (uint*)ptr.ToPointer();
for (int i = 0; i < 640*480; i++)
{
ptr2[i] = 0;
}
Marshal.FreeHGlobal(ptr);
}
}
PDWORD is a pointer to a 32-bit unsigned integer. In C#, that would be ref uint32
. Or IntPtr
if you're on the 32-bit runtime.
It depends on how you're going to use it. If you're passing it to unmanaged code, then I'd suggest the ref UInt32
. If you're using it for memory allocation (the return value from a Windows API function that allocates memory, for example), then you'd want to use IntPtr
.
PDWORD is a pointer to a DWORD. There are a few options to convert the code to C# depending on how it will be used.
For the DWORD itself you can use System.UInt32 as an equivalent. Marshal.AllocHGlobal might be a possibility as a replacement, but we would need to see how it's going to be used. Are you accessing the memory yourself or maybe passing it to another unmanaged function?
精彩评论