Search code examples
c#pinvokemarshalling

How do I read a uint from a pointer with Marshalling?


I have a native method which needs a pointer to write out a dword (uint).

Now I need to get the actual uint value from the (Int)pointer, but the Marshal class only has handy methods for reading (signed) integers.

How do I get the uint value from the pointer?

I've searched the questions (and Google), but couldn't really find what I needed.

Sample (not working) code:

IntPtr pdwSetting = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint)));

        try
        {
            // I'm trying to read the screen contrast here
            NativeMethods.JidaVgaGetContrast(_handleJida, pdwSetting);
            // this is not what I want, but close
            var contrast = Marshal.ReadInt32(pdwSetting);
        }
        finally
        {
            Marshal.FreeHGlobal(pdwSetting);
        }

The return value from the native function is a dword between 0 and 255 with 255 being full contrast.


Solution

  • Depending on whether you may use usafe code you can even do:

    static unsafe void Method()
    {
        IntPtr pdwSetting = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint)));
    
        try
        {
            NativeMethods.JidaVgaGetContrast(_handleJida, pdwSetting);
            var contrast = *(uint*)pdwSetting;
        }
        finally
        {
            Marshal.FreeHGlobal(pdwSetting);
        }
    }
    

    Note, that a C++ function pointer like

    void (*GetContrastPointer)(HANDLE handle, unsigned int* setting);
    

    can be marshaled as

    [DllImport("*.dll")]
    void GetContrast(IntPtr handle, IntPtr setting); // most probably what you did
    

    but also as

    [DllImport("*.dll")]
    void GetContrast(IntPtr handle, ref uint setting);
    

    which lets you write code like

    uint contrast = 0; // or some other invalid value
    NativeMethods.JidaVgaGetContrast(_handleJida, ref contrast);
    

    which is superior in both performance and readability.