【问题标题】:How to send the structure pointer to DeviceIoControl API in WINCE7 C#.net如何在 WINCE7 C#.net 中将结构指针发送到 DeviceIoControl API
【发布时间】:2014-03-18 12:11:24
【问题描述】:

我在WIN CE平台上工作,用C#.Net开发windows窗体。

DeviceIoControl API 与 c++ 控制台应用程序中的参数(如下所述)一起工作正常。

nuiouser.h 中的 PNIC_STATISTICS 结构

  global declarations :
  TCHAR PCI1_NAME[] = _T("PCI\\ManiXX1"); 
  TCHAR *AUB_NAME = NULL;       
  AUB_NAME = PCI1_NAME; 

   pNICStat = (PNIC_STATISTICS)malloc(sizeof(NIC_STATISTICS)) ;

   pNICStat->ptcDeviceName = AUB_NAME ;           //wchar_t* ptcDeviceName 

   DeviceIoControl( hUB94Port,                         //void*
                 IOCTL_NDISUIO_NIC_STATISTICS,
                 pNICStat,                         //PNIC_STATISTICS 
                 0,
                 pNICStat,                        //PNIC_STATISTICS 
                 sizeof(NIC_STATISTICS),
                 &dwReturnedBytes,
                 NULL
               );

但是我在使用 C#.Net CF for WIN-CE7 实现相同的问题时遇到了问题

我的WIN-CE代码如下:

C# 中的修改结构:

    [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)]
    public struct __NIC_STAT
    {

        ulong Size;               //  Of this structure.

        public Char[] ptcDeviceName;      //  The device name to be queried.. 

        ulong DeviceState;        //  DEVICE_STATE_XXX above
        ulong DeviceState;        //  DEVICE_STATE_XXX above
        ulong MediaType;          //  NdisMediumXXX
        ulong MediaState;         //  MEDIA_STATE_XXX above
        ulong PhysicalMediaType;
        ulong LinkSpeed;          //  In 100bits/s. 10Mb/s = 100000
        UInt64 PacketsSent;
        UInt64 PacketsReceived;
        ulong InitTime;           //  In milliseconds
        ulong ConnectTime;        //  In seconds
        UInt64 BytesSent;          //  0 - Unknown (or not supported)
        UInt64 BytesReceived;      //  0 - Unknown (or not supported)
        UInt64 DirectedBytesReceived;
        UInt64 DirectedPacketsReceived;
        ulong PacketsReceiveErrors;
        ulong PacketsSendErrors;
        ulong ResetCount;
        ulong MediaSenseConnectCount;
        ulong MediaSenseDisconnectCount; 

    } ;

从这个结构中,我只是填写 ptcDeviceName 并尝试发送。

 __NIC_STAT NIC_STAT = new __NIC_STAT();

  Char[] toBytes = {'P','C','I','\\','M','a','n','i','X','X','1','\0'}

  NIC_STAT.ptcDeviceName = toBytes;        //public Char[] ptcDeviceName; in structure 
                                      // __NIC_STAT this is the same structure as 
                                      //in  nuiouser.h     


    int sz = Marshal.SizeOf(NIC_STAT.GetType());//sometimes Getting exception here

     intptr ptr = Marshal.AllocHGlobal(sz);

     Marshal.StructureToPtr((__NIC_STAT)NIC_STAT, ptr, false);

   unsafe 
   {           

         DeviceIoControl(hFileHandle,
                     IOCTL_NDISUIO_NIC_STATISTICS,
                     ref ptr,
                     0,
                     ref ptr,
                     sz,
                     ref dwReturnedBytes,
                     0);
  }//unsafe

对应的原型

  [DllImport("coredll.dll", CharSet = CharSet.Auto, SetLastError = true)]
unsafe public static extern bool DeviceIoControl(
                                                  int hDevice, 
                                                  int dwIoControlCode, 
                                                  ref intptr InBuffer,
                                                  int nInBufferSize,
                                                  ref intptr OutBuffer,
                                                  int nOutputBufferSize, 
                                                  ref int pBytesReturned,
                                                  int pOverlapped
                                                 );

在 Win-CE 中,DeviceIoControl() 失败,出现异常并且不显示任何错误代码。有时会收到错误代码为 87 (INVALID PARAMETERS)。

我觉得 ptcDeviceName 造成了问题,或者可能是因为为指针 (ptr) 分配内存?

在控制台应用程序中,我们将 ptcDeviceName 作为 Wchar_t* 发送,但在 WIN-CE 中,所以我使用了

public Char[] ptcDeviceName;

谁能告诉我哪里做错了?

【问题讨论】:

  • __NIC_STAT 在 C# 中定义它与 nuiouser.h 中的 PNIC_STATISTICS 结构相同的结构 @cacke ctacke
  • 如果您隐瞒重要信息,我们如何为您提供帮助。我多次要求查看结构,但您不会显示它。
  • 你没有显示结构。不是你的 C# 翻译。我不会再问了。
  • @arya2arya 你不明白,是吗? // other parameter as in nuiouser.h 没有有帮助。我们需要查看整个结构。请将其复制并粘贴到您的问题中。有那么难吗?你为什么不明白这是我们需要帮助的信息!?
  • 不知道为什么关闭,这是一个有效的问题,我完全理解。既然结构已添加到问题中,我也知道问题是什么(还有多个问题),但在重新打开之前我无法提供答案。

标签: c# .net windows-ce


【解决方案1】:

这里有几个问题。

首先,您似乎认为 ulong 在 C# 中是 32 位的,但事实并非如此。它是 64 位,所以你的结构完全映射错误。

其次,我确定您需要先设置结构 Size 成员,然后再将其传递给调用。

第三,ptcDeviceName 成员是指向宽字符串的指针。这意味着在结构本身中它是 4 个字节。我可能会将其设为IntPtr。然后,您需要单独分配字符串,固定它,并将指向它的指针放入该成员槽中。由于 CF 中不存在`StringToHGlobal,它看起来像这样:

public struct __NIC_STAT
{
    public uint Size;
    public IntPtr ptcDeviceName;
    public uint DeviceState;
    public uint DeviceState;
    public uint MediaType;
    public uint MediaState;
    public uint PhysicalMediaType;
    public uint LinkSpeed;
    public ulong PacketsSent;
    public ulong PacketsReceived;
    public uint InitTime;
    public uint ConnectTime;
    public ulong BytesSent;
    public ulong BytesReceived;
    public ulong DirectedBytesReceived;
    public ulong DirectedPacketsReceived;
    public uint PacketsReceiveErrors;
    public uint PacketsSendErrors;
    public uint ResetCount;
    public uint MediaSenseConnectCount;
    public uint MediaSenseDisconnectCount;
};

....
var myStruct = new __NIC_STAT();
myStruct.Size = (15 * 4) + (6 * 8);
var name = "PCI\\Manixx1\0";
var nameBytes = Encoding.Unicode.GetBytes(name);
myStruct.ptcDeviceName = Marshal.AllocHGlobal(nameBytes.Length);
try
{
    Marshal.Copy(nameBytes, 0, myStruct.ptcDeviceName, nameBytes.Length);
    // make the IOCTL call, a-la
    NativeMethods.DeviceIoControl(...., ref myStruct, ....);
}
finally
{
    Marshal.FreeHGlobal(myStruct.ptcDeviceName);
}

【讨论】:

  • 我想你说的倒过来了,“似乎认为 ulong 是 32 位的,但事实并非如此。它是 64 位”不应该是“似乎认为 ulong 是 64 位,但是不是。它是 32 位的。”由于您指的是本机结构,而不是托管结构。
  • 我澄清了。 OP 使用 ulong 定义了 C# 结构,假设它们是 32 位的,但它们不是。
  • @ctacke 非常感谢!! :)
  • @ctacke MSDN 说紧凑型框架支持UnmanagedType.LPWStrmsdn.microsoft.com/en-us/library/ms172512.aspx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
相关资源
最近更新 更多