简体   繁体   中英

Can't convert a Marshal pointer of a struct back to struct

I'm coding a windows service that communicates with my driver, as such I'm trying to, as a test, pass a struct to it and get a returned struct.

In C++ this is working however in C# I'm not being able to convert an IntPtr to Struct using Marshal and that's why I'm not able to get the struct returned from the driver.

Struct:

[StructLayout(LayoutKind.Sequential)]
struct TestEst
{
    public int value;
}

Then in my driver:

typedef struct _TEST_EST
{
    int value;
} TEST_EST, *PTEST_EST;

And the code that is going to pass the struct via an IOCTL is:

void SendIOCTL<T>(IntPtr hDevice, uint dwIoControlCode, ref T inObj, ref T outObj)
    {
        IntPtr inPointer = IntPtr.Zero;
        IntPtr outPointer = IntPtr.Zero;
        int inObjSize = 0;
        int outObjSize = 0;
        uint bytesReturned = 0;

        if(inObj != null)
        {
            inObjSize = Marshal.SizeOf(inObj.GetType());
            inPointer = Marshal.AllocHGlobal(inObjSize);
            Marshal.StructureToPtr(inObj, inPointer, false);

            if (dwIoControlCode == TEST_CTL) // the TEST IOCTL
            {
                TestEst lets = new TestEst();

                Logger.Log("IsNull: " + (inPointer == IntPtr.Zero));
                Logger.Log("SizeObj: " + inObjSize);

                Marshal.PtrToStructure(inPointer, lets);
                Logger.Log("Working!: " + lets.value);
            }
        }
    }



public void SendTest()
    {
        TestEst request = new TestEst();
        TestEst result = new TestEst();

        request.value = 30;

        SendIOCTL(hDriver, TEST_CTL, ref request, ref result);

        Logger.Log("RA: " + result.value + " " + request.value);
    }

Logger.Log() simply writes an entry to the windows event viewer.

I omitted the actual DeviceIoControl because that's not where this fails, what is happening is in the

Marshal.PtrToStructure(inPointer, lets);

Is causing my service to show this in the logs:

Windows事件查看器

And the inPointer is not null and inObjSize is 4

I also tried removing the T, A from the SendIOCTL and placing only T but it's the same.

Thanks in advance

To marshal pointer to structure use this approach

var test = (T) Marshal.PtrToStructure(inPointer, typeof(T));

Do not forget to use Marshal.FreeHGlobal(inPointer) when you're done with our allocated memory blocks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM