C# 为什么当C中的等效程序正常工作时,DeviceIoControl从C中抛出错误21(设备未就绪)?

C# 为什么当C中的等效程序正常工作时,DeviceIoControl从C中抛出错误21(设备未就绪)?,c#,c,windows-mobile,gps,pinvoke,C#,C,Windows Mobile,Gps,Pinvoke,我正在尝试使用C向GPS中间驱动程序服务发送一个IOCTL_SERVICE_REFRESH命令,如下所示: handle = CreateFile("GPD0:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (handle.ToInt32() == I

我正在尝试使用C向GPS中间驱动程序服务发送一个IOCTL_SERVICE_REFRESH命令,如下所示:

handle = CreateFile("GPD0:",
    GENERIC_READ,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    IntPtr.Zero,
    OPEN_EXISTING, 
    FILE_ATTRIBUTE_NORMAL, 
    IntPtr.Zero);

if (handle.ToInt32() == INVALID_HANDLE_VALUE)
{
    rc = Marshal.GetLastWin32Error();
    return rc;
}

int numBytesReturned = 0;

rc = DeviceIoControl(
    handle,
    IOCTL_SERVICE_REFRESH,
    null,
    0,
    null,
    0,
    ref numBytesReturned,
    IntPtr.Zero);

int error = Marshal.GetLastWin32Error();
GetLastWin32Error总是给我错误21(设备未就绪)。然而,C++所做的等效调用工作精细:

HANDLE hGPS = CreateFile(L"GPD0:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hGPS != INVALID_HANDLE_VALUE) {
  BOOL ret = DeviceIoControl(hGPS,IOCTL_SERVICE_REFRESH,0,0,0,0,0,0);
  DWORD err = GetLastError();       
}
我怀疑PInvoke签名有问题,但我在这里似乎没有发现任何错误:

[DllImport("coredll.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
public static extern int DeviceIoControl(
    IntPtr hDevice,
    uint dwIoControlCode,
    byte[] lpInBuffer,
    int nInBufferSize,
    byte[] lpOutBuffer,
    int nOutBufferSize,
    ref int lpBytesReturned,
    IntPtr lpOverlapped);

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr CreateFile(
    String lpFileName,
    uint dwDesiredAccess,
    uint dwShareMode,
    IntPtr attr,
    uint dwCreationDisposition,
    uint dwFlagsAndAttributes,
    IntPtr hTemplateFile);

我在这里遗漏了什么?

您确定C版本可以工作吗?文档()说“如果lpBytesReturned为NULL,则lpBytesReturned不能为NULL。即使操作未返回任何输出数据且lpburffer为NULL,DeviceIoControl也会使用lpBytesReturned。”并且在C调用中为该参数传递NULL(0)。代码声明C#P/Invoke具有ref参数,但是调用代码没有传递任何ref参数,所以我猜您在这里发布的东西eitehr不会编译,或者您有另一个重载声明。在任何情况下,我们都没有完整的故事。@Gabe,我不认为参数在CE中是必需的。我当然不记得曾经通过过它(尽管也许我从未尝试过不通过)。ctacke:没有说任何东西表明
lpbytesreeted
是可选的,所以我认为它不是。@Ragesh-我仍然感到困惑
rc
被分配GetLastWin32Error的结果,表示它是一个int。您还可以使用它从DeviceIoControl返回,它返回一个BOOL(公认为32位)。这似乎不匹配。您也没有查看DeviceIoControl的返回值以查看它是否实际失败。在没有实际故障指示的情况下检查最后一个错误是毫无意义的。