Avatar billede rrm Nybegynder
23. august 2008 - 00:19 Der er 1 kommentar

Returnering af en konpleks struktur fra en dll

Jeg fik hjælp til at kalde en c++ dll funktion med en struktur i dette spm: http://www.eksperten.dk/spm/842083.

Men jeg har også funktioner der returnere strukturer og for tiden har jeg klaret det ved:

namespace wpGrabDotNet.DllCode
{
  public class PointerToStruct<T> : IDisposable
    where T : struct
  {
    private T? outputStruct = null;

    public T? ToStruct
    {
      get
      {
        return outputStruct;
      }
    }

    public PointerToStruct(IntPtr ptr)
    {
      try
      {
        if (ptr != IntPtr.Zero)
        {
          //outputStruct = new T();
          outputStruct = (T) Marshal.PtrToStructure(ptr, typeof(T));
        }
      }
      catch(Exception ex)
      {
        outputStruct = null;
        throw new Exception(ex.Message);
      }
    }

    public void Dispose()
    {
      outputStruct = null;
    }
  }
}

Og strukturen der modtages er defineret ved (WPGRAB_STATUS_ENUM er en enumeration):

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

    [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;
    };

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

Jeg kalder så dll funktionen med:

[DllImport(DLL_NAME, CallingConvention = DLL_CC, CharSet = DLL_CHAR_SET, EntryPoint = "WPGrabGetFoundResources")]
private static extern IntPtr WPGrabGetFoundResourcesInt(int index);

public static WPGrabResourceFoundStruct? WPGrabGetFoundResources(int index)
    {
      using (var output = new PointerToStruct<WPGrabResourceFoundStructInt>(WPGrabGetFoundResourcesInt(index)))
      {
        WPGrabResourceFoundStruct tmp = new WPGrabResourceFoundStruct();
        tmp.webpagesList = (WPGrabUrlResourceStruct?) (new PointerToStruct<WPGrabUrlResourceStruct>(output.ToStruct.Value.webpagePtr)).ToStruct;
        tmp.imagesList = (WPGrabUrlResourceStruct?)(new PointerToStruct<WPGrabUrlResourceStruct>(output.ToStruct.Value.imagePtr)).ToStruct;
        tmp.otherList = (WPGrabUrlResourceStruct?)(new PointerToStruct<WPGrabUrlResourceStruct>(output.ToStruct.Value.otherPtr)).ToStruct;

        return tmp;
      }
    }

Det virker meget besværligt... Er man virkelig nødt til selv at kopiere inner strukturer (f.eks. webpagesList) som kan være nullable??? Eller er der en bedre løsning???
Avatar billede rrm Nybegynder
23. august 2008 - 00:22 #1
Jeg kan se at jeg har udkommenteret

if (ptr != IntPtr.Zero)
{
//outputStruct = new T();
outputStruct = (T) Marshal.PtrToStructure(ptr, typeof(T));
}

Sørger Marshal.PtrToStructure selv for at allokere et object?? "Marshals data from an unmanaged block of memory to a newly allocated managed object of the specified type." lyder som man selv skal oprette objektet....?
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