【问题标题】:Can't convert a Marshal pointer of a struct back to struct无法将结构的元帅指针转换回结构
【发布时间】:2017-08-20 14:12:15
【问题描述】:

我正在编写一个与我的驱动程序通信的 Windows 服务,因此我试图作为测试将一个结构传递给它并获取一个返回的结构。

在 C++ 中这是可行的,但在 C# 中我无法使用 Marshal 将 IntPtr 转换为 Struct,这就是为什么我无法从驱动程序中获取返回的结构。

结构:

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

然后在我的驱动程序中:

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

通过 IOCTL 传递结构的代码是:

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() 只是将一个条目写入 Windows 事件查看器。

我省略了实际的 DeviceIoControl,因为这不是失败的地方,正在发生的事情是在

Marshal.PtrToStructure(inPointer, lets);

导致我的服务在日志中显示:

并且inPointer不为null,inObjSize为4

我还尝试从 SendIOCTL 中删除 T、A 并仅放置 T,但它是相同的。

提前致谢

【问题讨论】:

    标签: c# c++ pointers windows-services marshalling


    【解决方案1】:

    使用这种方法来编组指向结构的指针

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

    使用完我们分配的内存块后,不要忘记使用Marshal.FreeHGlobal(inPointer)

    【讨论】:

    • 哦,即使在 FreeHGlobal 之后,我的结构也会保留,对吗?
    • @L3n 当然可以。您将释放非托管内存,并且您的结构仍处于托管状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    • 2020-09-18
    • 2023-03-16
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多