如何在C#中编写NDISUIO_QUERY_OID结构以执行以下任务

时间:2014-03-26 14:46:18

标签: c# c++ .net pinvoke windows-embedded-compact

您好我正在尝试将C / C ++ Strcut转换为C#以及如何使用C#中的另一个结构的地址填充结构成员?

C / C ++ Struct看起来像:

         typedef struct _NDISUIO_QUERY_OID
         {
           NDIS_OID        Oid;
           PTCHAR          ptcDeviceName;  
           UCHAR           Data[sizeof(ULONG)];
         } NDISUIO_QUERY_OID, *PNDISUIO_QUERY_OID;

         typedef struct My_Struct
         {
           //leT's have 2 variables...  
            UINT    a;
            UINT    b;
           //sTRUCT may have many no.of variables depending upon the requirement
         }My_STATS, *PMy_STATS;

         PNDISUIO_QUERY_OID     pQueryOid = NULL;

          pQueryOid = (PNDISUIO_QUERY_OID)malloc(sizeof(NDISUIO_QUERY_OID)+ sizeof(My_STATS)) ;

          PMy_STATS   Statistics;
          pQueryOid->Oid = ulOIDCode;//Required OID
      pQueryOid->ptcDeviceName = AUB_NAME;//REquired STRING

          memcpy(pQueryOid->Data, Statistics, sizeof(My_STATS));

          IoctlResult = DeviceIoControl(
                                       handle,
                                       IOCTL_NDISUIO_QUERY_OID_VALUE,
                                       pQueryOid,
                                       sizeof(NDISUIO_QUERY_OID)+ sizeof(My_STATS),
                                       pQueryOid,
                                       sizeof(NDISUIO_QUERY_OID)+ sizeof(My_STATS),
                                       &dwReturnedBytes,
                                       NULL);

在C ++中获得IoctlResult成功;

我的C#Struct是:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]           
    public struct _NDISUIO_QUERY_OID
    {
        public uint        Oid;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string          ptcDeviceName;
        [MarshalAs(UnmanagedType.ByValArray,SizeConst = sizeof(uint))]
        public byte[] Data;
    };

     My_STATS Sta_Conn_Info = new My_STATS();
     _NDISUIO_QUERY_OID QueryOid = new _NDISUIO_QUERY_OID();

    QueryOid.Oid = ulOIDCode; // required OID
    QueryOid.ptcDeviceName = STRING;//Required String

    //Imported coredll.dll with required prototype for this.
    IoctlResult = DeviceIoControl(
                                       handle,
                                       IOCTL_NDISUIO_QUERY_OID_VALUE,
                                       ref QueryOid,
                                       sizeof(NDISUIO_QUERY_OID)+ sizeof(My_STATS),
                                       ref QueryOid,
                                       sizeof(NDISUIO_QUERY_OID)+ sizeof(My_STATS),
                                       ref dwReturnedBytes,
                                       NULL
                                  );

问题:如何编组NDISUIO_QUERY Struct将另一个结构复制到C#中的数据成员?以及如何在c ++中替换memcpy?

任何建议或指南都会有所帮助.. :)

谢谢:)

1 个答案:

答案 0 :(得分:1)

Data成员不是它看起来的样子。它是一个占位符,结构实际上是可变长度的。我想我会倾向于手动使用Marshal.AllocHGlobal和编组。但你似乎更喜欢声明一个C#结构。只要你使用的结构总是相同的那么你就会这样声明:

[StructLayout(LayoutKind.Sequential)]           
public struct NDISUIO_QUERY_OID
{
    public uint Oid;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ptcDeviceName;
    uint a;
    uint b;
};

这与您提供的C ++代码不完全匹配,因为它声明结构的大小为sizeof(NDISUIO_QUERY_OID)+ sizeof(My_STATS),但随后将My_STATS结构复制到Data而不是Data之后}。

更一般地说,你现在基本上问了七次问题。我认为现在可能是时候退后一步,尝试更好地理解内存布局了。每次提出问题时,都没有明确说明要用于NDISUIO_QUERY_OID结构版本的布局。现在是你在脑海中清醒过的最佳时机。