无法将结构的 Marshal 指针转换回结构
Can't convert a Marshal pointer of a struct back to struct
我正在编写一个 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 不为空且 inObjSize 为 4
我也试过从 SendIOCTL 中删除 T、A 并只放置 T,但它是一样的。
提前致谢
要编组指向结构的指针,请使用此方法
var test = (T) Marshal.PtrToStructure(inPointer, typeof(T));
当你完成我们分配的内存块时,不要忘记使用 Marshal.FreeHGlobal(inPointer)
。
我正在编写一个 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 不为空且 inObjSize 为 4
我也试过从 SendIOCTL 中删除 T、A 并只放置 T,但它是一样的。
提前致谢
要编组指向结构的指针,请使用此方法
var test = (T) Marshal.PtrToStructure(inPointer, typeof(T));
当你完成我们分配的内存块时,不要忘记使用 Marshal.FreeHGlobal(inPointer)
。