[英]C# USB driver from C++
I've a problem trying to call SetupDiEnumDeviceInterfaces from C#. 我在尝试从C#调用SetupDiEnumDeviceInterfaces时遇到问题。 It always returns 1784 error code ("The supplied user buffer is not valid for the requested operation").
它始终返回1784错误代码(“提供的用户缓冲区对于请求的操作无效”)。 On the same machine if I execute the corrisponding C++ code the function is successful.
在同一台机器上,如果我执行相应的C ++代码,该函数将成功执行。 This is my C# code:
这是我的C#代码:
Guid classGuid = GUID_DEVINTERFACE_DFU; // Guid(0x3fe809ab, 0xfb91, 0x4cb5, 0xa6, 0x43, 0x69, 0x67, 0x0d, 0x52,0x36,0x6e)
IntPtr hDevInfo = Win32.SetupDiGetClassDevs(ref classGuid, IntPtr.Zero, IntPtr.Zero, Win32.DIGCF_DEVICEINTERFACE | Win32.DIGCF_PRESENT);
if (hDevInfo.ToInt32() == Win32.INVALID_HANDLE_VALUE)
{
Console.WriteLine("read hardware information error");
}
else
{
uint i = 0;
SP_DEVINFO_DATA devInfoData = new SP_DEVINFO_DATA();
devInfoData.classGuid = Guid.Empty;
devInfoData.devInst = 0;
devInfoData.reserved = IntPtr.Zero;
bool result = Win32.SetupDiEnumDeviceInfo(hDevInfo, i, devInfoData);
if (false == result)
{
int error = Marshal.GetLastWin32Error();
if (error != Win32.ERROR_NO_MORE_ITEMS)
throw new Win32Exception(error);
}
SP_DEVICE_INTERFACE_DATA ifData = new SP_DEVICE_INTERFACE_DATA();
ifData.cbSize = 50;
ifData.Flags = 0;
ifData.InterfaceClassGuid = Guid.Empty;
ifData.Reserved = IntPtr.Zero;
bool result2 = Win32.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref classGuid, i, ref ifData);
if(result2 == false)
{
int error = Marshal.GetLastWin32Error();
if (error != Win32.ERROR_NO_MORE_ITEMS)
throw new Win32Exception(error);
}
}
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINFO_DATA
{
public uint cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
public Guid classGuid;
public uint devInst;
public IntPtr reserved;
};
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public class SP_DEVICE_INTERFACE_DATA
{
public uint cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA));
public Guid InterfaceClassGuid;
public uint Flags;
public IntPtr Reserved;
}
public class Win32
{
[DllImport("setupapi.dll", SetLastError = true)]
public static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, uint Flags);
[DllImport("setupapi.dll", SetLastError = true)]
public static extern Boolean SetupDiEnumDeviceInfo(IntPtr lpInfoSet, UInt32 dwIndex, SP_DEVINFO_DATA devInfoData);
public const int DIGCF_PRESENT = 0x02;
public const int DIGCF_DEVICEINTERFACE = 0x10;
public const long ERROR_NO_MORE_ITEMS = 259L;
}
And this is my C++ code: 这是我的C ++代码:
GUID Guid=GUID_DFU; // { 0x3fe809ab, 0xfb91, 0x4cb5, { 0xa6, 0x43, 0x69, 0x67, 0x0d, 0x52,0x36,0x6e } }
HDEVINFO info = SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if (info!=INVALID_HANDLE_VALUE)
{
SP_INTERFACE_DEVICE_DATA ifData;
ifData.cbSize=sizeof(ifData);
bool result = SetupDiEnumDeviceInterfaces(info, NULL, &Guid, devIndex, &ifData);
}
The code is running on Windows 8.1 x64 and the C# application platform is x86. 该代码在Windows 8.1 x64上运行,C#应用程序平台为x86。
You declare SP_DEVICE_INTERFACE_DATA
to be a class in the C# code. 您将
SP_DEVICE_INTERFACE_DATA
声明为C#代码中的类。 That means that it is already a reference. 这意味着它已经是参考。 You then pass the
SP_DEVICE_INTERFACE_DATA
instance by reference to SetupDiEnumDeviceInfo
. 然后,通过引用
SetupDiEnumDeviceInfo
传递SP_DEVICE_INTERFACE_DATA
实例。 Which means that you are passing SP_DEVICE_INTERFACE_DATA**
rather than SP_DEVICE_INTERFACE_DATA*
, in C++ terms. 这意味着您使用C ++术语传递了
SP_DEVICE_INTERFACE_DATA**
而不是SP_DEVICE_INTERFACE_DATA*
。
Either: 要么:
SP_DEVICE_INTERFACE_DATA
to be a struct, or SP_DEVICE_INTERFACE_DATA
更改为结构,或者 SP_DEVICE_INTERFACE_DATA
as a class, but pass it by value. SP_DEVICE_INTERFACE_DATA
保留为类,但按值传递它。 That is, as you did with SP_DEVINFO_DATA
and SetupDiEnumDeviceInfo
. SP_DEVINFO_DATA
和SetupDiEnumDeviceInfo
。 You are setting cbSize
incorrectly. 您设置的
cbSize
错误。 It should be: 它应该是:
ifData.cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA));
There's no point in setting the other members of SP_DEVICE_INTERFACE_DATA
since they are ignored by the function that you call. 设置
SP_DEVICE_INTERFACE_DATA
的其他成员没有任何意义,因为您调用的函数将忽略它们。 That function's job is to populate those members. 该职能部门的职责是填充这些成员。
There may be other problems. 可能还有其他问题。 It's hard to say because you have not posted your actual code.
很难说,因为您尚未发布实际代码。 The C++ code does not compile, and the C# code is incomplete.
C ++代码无法编译,并且C#代码不完整。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.