1

こんにちは、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
         {
           //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#構造体は次のとおりです。

    [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 構造体をマーシャリングして、別の構造体を C# のデータ メンバーにコピーする方法?? c ++のようにmemcpyを置き換える方法は?

どんな提案やガイドラインも役に立ちます.. :)

ありがとう :)

4

1 に答える 1

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++ コードとは完全には一致しません。これは、構造体にサイズがあることを宣言し、構造体をafterではなくsizeof(NDISUIO_QUERY_OID)+ sizeof(My_STATS)コピーするためです。My_STATSDataData

より一般的に言えば、あなたは基本的に 7 回質問をしました。一歩下がって、現在よりもメモリ レイアウトをよりよく理解しようとする時が来ているのではないかと思います。質問をするたびに、構造体のバージョンに使用したいレイアウトを明確に述べていませんNDISUIO_QUERY_OID。心の中でそれを明確にする時が来ました。

于 2014-03-26T15:09:49.577 に答える