Avatar billede rrm Nybegynder
31. august 2008 - 23:08

Marshal Strukture med arrays og string

Jeg har en funktion, der får følgende struktur som input:

    [StructLayout(LayoutKind.Sequential, CharSet=DLL_CHAR_SET)]
    public struct WPGrabUrlResourceStruct
    {
      public int id;
      public int masterId;
      public int errCode;
      public string url;
      public string errMsg;
      public WPGRAB_STATUS_ENUM status;
    };

    public struct WPGrabResourceFoundStruct
    {
      public int masterId;
      public WPGrabUrlResourceStruct[] webpagesList;
      public WPGrabUrlResourceStruct[] imagesList;
      public WPGrabUrlResourceStruct[] otherList;
    };

Den skal jeg have konvertere til strukturen:

[StructLayout(LayoutKind.Sequential)]
    public struct WPGrabResourceFoundStructInt
    {
      public int masterId;
      public int webpageCount;
      public int imagesCount;
      public int otherCount;
      public IntPtr webpagePtr;
      public IntPtr imagePtr;
      public IntPtr otherPtr;
    };

For at kunne kalde en dll funktion, der har til opgave af frigøre hukommelse.

Jeg har forsøgt med (efter inspiration fra http://forums.msdn.microsoft.com/en-US/csharpgeneral/thread/a0cdf1eb-64a2-4893-9b52-14649006d5d8/):

    [DllImport(DLL_NAME, CallingConvention = DLL_CC, CharSet = DLL_CHAR_SET, EntryPoint = "WPGrabFreeFoundResourcesStruct")]
    private static extern void WPGrabFreeFoundResourcesStructInt(IntPtr resources);

    public static void WPGrabFreeFoundResourcesStruct(WPGrabResourceFoundStruct? resources)
    {
      if (resources != null)
      {
        WPGrabResourceFoundStructInt tmp = new WPGrabResourceFoundStructInt();
        int sizeOfStruct = 0;
        Int64 addr = 0;

        tmp.masterId = resources.Value.masterId;
        tmp.webpageCount = resources.Value.webpagesList.GetLength(0);

        if (tmp.webpageCount > 0)
        {
          sizeOfStruct = Marshal.SizeOf(resources.Value.webpagesList.GetValue(0)); //Marshal.SizeOf(resources.Value.webpagesList.GetValue(0));
          tmp.webpagePtr = Marshal.AllocHGlobal(sizeOfStruct  * tmp.webpageCount);
          addr = tmp.webpagePtr.ToInt64();

          for (int i = 0; i < tmp.webpageCount; i++)
          {
            Marshal.StructureToPtr(resources.Value.webpagesList[i], (IntPtr) (addr + i * sizeOfStruct), false);
          // tmp.webpagePtr[addr + i * sizeOfStruct] = (new StructToPointer<WPGrabUrlResourceStruct>(resources.Value.webpagesList(i)).ToPtr)
          }
        }
        else
        {
          tmp.webpagePtr = IntPtr.Zero;
        }

        tmp.imagesCount = 0;
        tmp.imagePtr = IntPtr.Zero;

        tmp.otherCount = 0;
        tmp.otherPtr = IntPtr.Zero;

        using (var t = new StructToPointer<WPGrabResourceFoundStructInt>(tmp))
        {
          WPGrabFreeFoundResourcesStructInt(t.ToPtr);
        }
      }
    }

StructToPointer kan findes her: http://www.eksperten.dk/spm/842083.

Mit problem er at når jeg køre programmet, så får jeg fint allokeret hukommelsen og i WPGrabFreeFoundResourcesStructInt kan jeg se de data jeg sender med, men når jeg via delete[] errMsg (fra WPGrabUrlResourceStruct), så får jeg assertion. Nogen ideer til hvad problemet er???
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester