Как маршалировать структуру NDISUIO_QUERY_OID в C# для выполнения следующей задачи

Привет, я пытаюсь преобразовать Strcut C/C++ в 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);

Получение успеха 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#?? а как заменить memcpy как в c++?

Любые предложения или рекомендации будут полезны .. :)

Спасибо :)


person arya2arya    schedule 26.03.2014    source источник
comment
возможный дубликат преобразования структуры C/C++ в C#.Net CF Вздрогнуть   -  person Hans Passant    schedule 26.03.2014
comment
@HansPassant привет, сэр. Преобразование структуры здесь не вызывает проблем, мне нужно выполнить задачу, как на C #, так как работая на C ++, я добавил код на C ++.   -  person arya2arya    schedule 26.03.2014
comment
@HansPassant В C++ я копирую одну структуру в элемент данных другой структуры, используя memcpy. Та же задача, которую я пытаюсь выполнить на С#   -  person arya2arya    schedule 26.03.2014
comment
Как я сказал вам в последнем вопросе, вы не можете объявить NDISUIO_QUERY_OID как структуру C#. Вы должны использовать Marshal.AllocHGlobal.   -  person David Heffernan    schedule 26.03.2014
comment
@DavidHeffernan Сэр .. Я попытался преобразовать структуру в указатель и выделить память с помощью Marshal.AllocHGlobal, но не смог получить результат.   -  person arya2arya    schedule 26.03.2014
comment
@ arya2arya Не согласно вопросу. Вы продолжаете задавать один и тот же вопрос снова и снова. Я не вижу никакого кода, указывающего, что вы пробовали.   -  person David Heffernan    schedule 26.03.2014
comment
@DavidHeffernan Сэр, пожалуйста, проверьте свой чат. Я разместил свой код, который я реализовал.   -  person arya2arya    schedule 26.03.2014


Ответы (1)


Участник Data не тот, кем кажется. Это заполнитель, а структура на самом деле имеет переменную длину. Я думаю, что я был бы склонен использовать Marshal.AllocHGlobal и маршалировать вручную. Но вы, похоже, предпочитаете объявлять структуру С#. Пока структура, которую вы используете, всегда одна и та же, вы должны объявить ее следующим образом:

[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. Давно пора уяснить себе это.

person David Heffernan    schedule 26.03.2014
comment
Спасибо, сэр!! У меня нет глубоких знаний в .Net CF, я начал свою задачу с преобразования C++ в C#, просмотрев несколько руководств, способных делать некоторые базовые вещи. это последнее дело. Я должен сделать структуру правильно, а затем отправить ее в DeviceIoControl() - person arya2arya; 26.03.2014