Jump to content
  • Advertisement
Sign in to follow this  
PaulCesar

[.net] Managed type to IntPtr

This topic is 3173 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Good Morning GameDev, I am not getting much luck on IRC lately, so I figured I would try here, as gamedev is usually fairly responsive. I am using C# and .NET 4.0 (MSVS 2010) I recently ran into the need to pass a managed type THROUGH an unmanaged callback. (EnumThreadWindows in this case). Both the function and its callback work with an IntPtr, and both "endpoints" are in managed code. So basically I need an IntPtr to a managed class (struct actually, although I am fairly positive its the same internally). Since both endpoints are in managed code, I do not believe the intptr even really needs to be valid in an unmanaged context. As a temporary fix I am passing an int in intptr's place, and storing that in an ad-hoc nasty collection. This _IS_ a huge bottleneck and truthfully dispicable code. It needs to go. Hopefully one of you .NET geniuses can help with this one :) Thanks, Richard edit: to further clarify, I am using the following PINVOKE signatures for the enumwindow code
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

        public delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

Share this post


Link to post
Share on other sites
Advertisement
I assume it's the lParam thats giving you problems, since HWND's is the Handle member of a control. lParam is usually an int (DWORD in unmanaged Win32) and you can create an IntPtr from an Int32 directly.

If you need something more complex you can take a look at Marshal.StructureToPtr. It should do what you need.

Share this post


Link to post
Share on other sites
Yes, you are correct it is using the lparam that is giving me problems. In C++ I would always simply use a void* to a class or structure on the heap, and cast it however I needed.

Anyways, I did some research based on what you said, and I thought I came up with the solution, but somehow it is returning the wrong results. Am I doing this wrong?:


public void PollThreadWindows(UInt32 process_id, UInt32 thread_id)
{
ProcessThreadMap ptm = new ProcessThreadMap();
ptm.process_id = process_id;
ptm.thread_id = thread_id;
Trace.WriteLine("this: "+ptm.process_id.ToString());
IntPtr umPtm = Marshal.AllocHGlobal(Marshal.SizeOf(ptm));
Win32.EnumThreadWindows(thread_id, new Win32.EnumThreadDelegate(EnumThreadCallback), umPtm);
Marshal.FreeHGlobal(umPtm);
}

public bool EnumThreadCallback(IntPtr hWnd, IntPtr lParam)
{
ProcessThreadMap ptm = (ProcessThreadMap)Marshal.PtrToStructure(lParam, typeof(ProcessThreadMap));
Trace.WriteLine("becomes "+ptm.process_id.ToString());
//process_map[ptm.process_id].threads[ptm.thread_id].windows.Add((uint)hWnd, "test window");
return true;
}


an example of the trace is:

this: 1616
becomes 2155104

Share this post


Link to post
Share on other sites
In case it matters, ProcessThreadMap is defined as:


public struct ProcessThreadMap
{
public UInt32 process_id;
public UInt32 thread_id;
}

Share this post


Link to post
Share on other sites
StructureToPtr actually moves the given managed object into unmanaged memory. If you just want a pointer to the managed object while it's still on the managed heap, you can use GCHandle to pin the object and get a pointer to the pinned data. Once you're done you'll have to unpin it so that the garbage collector can continue to deal with it.

Share this post


Link to post
Share on other sites
Mike,

Thank you, that worked PERFECTLY. I would still love to know why the previous code did not work though, if nothing else for shits and giggles. But thank you both so much for your quick response and awsome direction. Proves once again the best coders are on gamedev :)

Richard

Edit:

Funniest thing. The example on MSDN was doing something very similar to what I have. Almost like they had this in mind!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!