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

C / C++结构看起来像:

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

         typedef struct My_Struct
         {
           //les have 2 variables...
            UINT    a;
            UINT    b;
         }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));

我的C#结构是:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

    public struct _NDISUIO_QUERY_OID
    {
        public uint        Oid;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string          ptcDeviceName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = sizeof(uint))]
        public string Data;
    };

问题:如何在C#中将统计信息结构复制到数据数组?

谢谢 :)

最佳答案

这是我的实现(仅供引用,SDF包含所有这些代码以及更多内容)

internal class NDISQueryOid
{
    protected const int NDISUIO_QUERY_OID_SIZE = 12;

    protected byte[] m_data;
    public int Size { get; private set; }

    public NDISQueryOid(byte[] data)
    {
        int extrasize = data.Length;
        Size = 8 + extrasize;
        m_data = new byte[Size];
        Buffer.BlockCopy(data, 0, m_data, DataOffset, data.Length);
    }

    public NDISQueryOid(int extrasize)
    {
       Size = NDISUIO_QUERY_OID_SIZE + extrasize;
        m_data = new byte[Size];
    }

    protected const int OidOffset = 0;
    public uint Oid
    {
        get { return BitConverter.ToUInt32(m_data, OidOffset); }
        set
        {
            byte[] bytes = BitConverter.GetBytes(value);
            Buffer.BlockCopy(bytes, 0, m_data, OidOffset, 4);
        }
    }

    protected const int ptcDeviceNameOffset = OidOffset + 4;
    public unsafe byte* ptcDeviceName
    {
        get
        {
            return (byte*)BitConverter.ToUInt32(m_data, ptcDeviceNameOffset);
        }
        set
        {
            byte[] bytes = BitConverter.GetBytes((UInt32)value);
            Buffer.BlockCopy(bytes, 0, m_data, ptcDeviceNameOffset, 4);
        }
    }

    protected const int DataOffset = ptcDeviceNameOffset + 4;
    public byte[] Data
    {
        get
        {
            byte[] b = new byte[Size - DataOffset];
            Array.Copy(m_data, DataOffset, b, 0, Size - DataOffset);
            return b;
        }
        set
        {
            Size = 8 + value.Length;
            m_data = new byte[Size];
            Buffer.BlockCopy(value, 0, m_data, DataOffset, value.Length);
        }
    }

    public byte[] getBytes()
    {
        return m_data;
    }

    public static implicit operator byte[](NDISQueryOid qoid)
    {
        return qoid.m_data;
    }
}

请注意,在我的用法中,NDIS IOCT接收了一个指针(我的大多数NDIS工作都是不安全的),因此您必须在此处进行一些调整。

因此,例如,如果您要查询BSSID,我知道BSSID数据是36个字节,因此我将创建如下内容:
var queryOID = new NDISQueryOid(36);

然后分配名称并调用NDIS(生产代码比这更多的检查):
byte[] nameBytes = System.Text.Encoding.Unicode.GetBytes(adapterName + '\0');

fixed (byte* pName = &nameBytes[0])
{
    queryOID.ptcDeviceName = pName;
    queryOID.Oid = (uint)oid;

    var bytes = queryOID.getBytes();
    ndis.DeviceIoControl(IOCTL_NDISUIO_QUERY_OID_VALUE, bytes, bytes);

    var result = new byte[queryOID.Data.Length];
    Buffer.BlockCopy(queryOID.Data, 0, result, 0, result.Length);
}

编辑

因此,上面的result成员是查询“结果”的字节数组。它的含义和解释方式取决于您查询的OID是什么。例如,如果您要查询当前连接的SSID(即NDIS_OID.SSID),那么它将以4个字节的长度返回,后跟ASCII编码的名称,因此您可以这样解密:
int len = BitConverter.ToInt32(data, 0);
if (len > 0)
{
    ssid = System.Text.Encoding.ASCII.GetString(data, 4, len);
}

但是同样,这仅适用于一个特定的OID。您必须为您决定支持的每个传入OID处理所有退货情况。

关于c# - 如何使用以下任务在C#.Net CF中执行memcpy,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22604111/

10-11 09:07