[Mono-list] Memory Allocation in unmanaged code

Jim Fehlig jfehlig@novell.com
Fri, 03 Sep 2004 18:10:32 -0600


This is a MIME message. If you are reading this text, you may want to 
consider changing to a mail reader or gateway that understands how to 
properly handle MIME multipart messages.

--=__PartFFDF8AE8.0__=
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

I am having difficulty with a C# wrapper for some unmanaged C code that
allocates a list.  Unmanaged code snippet: 
   typedef struct CupsPrinterListStruct 
   { 
       char printerUri[1024]; 
       char printerCupsUri[1024]; 
       char printerName[1024]; 
       char printerMakeAndModel[256]; 
       struct CupsPrinterListStruct *nextPtr; 
   }CupsPrinterList; 
   int ListLocalPrinters(CupsPrinterList **printerList); 
   int FreeLocalPrinterList(CupsPrinterList *listHead); 
 
Wrapper code: 
   [ StructLayout(LayoutKind.Sequential) ] 
      public struct PrinterList 
      { 
         [ MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024) ] 
         public string printerUri; 
         [ MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024) ] 
         public string printerCupsUri; 
         [ MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024) ] 
         public string printerName; 
         [ MarshalAs(UnmanagedType.ByValTStr, SizeConst=256) ] 
         public string printerMakeModel; 
         public IntPtr nextElement; 
    } 
   public class PrintLibWrapper 
   { 
      [ DllImport(print) ] 
      public static extern int ListLocalPrinters( ref PrinterList pl); 
   } 
 
Usage: 
   PrinterList printers = new PrinterList(); 
   printers.nextElement = IntPtr.Zero; 
   int ccode = PrintLibWrapper.ListLocalPrinters(ref printers); 
   Console.WriteLine(printer name = + printers.printerName); //
printers.printerName is empty 
 
I can successfully call ListLocalPrinters but unable to read even 1
result let alone iterate through the list.  Seems I need another level
of indirection (perhaps an IntPtr) when calling
PrintLibWrapper.ListLocalPrinters().  Didn't try this as I could not
figure out how to describe unmarshalling of the returned data.   Any
pointers to additional info/examples would be appreciated.  Was hoping
to find an example in gtk-sharp (List.cs, ListBase.cs) but no
marshalling of memory allocated by unmanaged code found there. 
 
Thanks. 
Jim 


--=__PartFFDF8AE8.0__=
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <style type=3D"text/css">
      <!--
        body { font-variant: normal; margin-right: 4px; margin-bottom: =
1px; margin-top: 4px; margin-left: 4px; line-height: normal }
      -->
    </style>
   =20
  </head>
  <body>
    <DIV>
      I am having difficulty with a C# wrapper for some unmanaged C code =
that allocates a list. &nbsp;Unmanaged code snippet:
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;typedef struct CupsPrinterListStruct
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;{
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char printerUri[1024];
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char printerCupsUri[1024];
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char printerName[1024];
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char printerMakeAndModel[25=
6];
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct CupsPrinterListStruc=
t *nextPtr;
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;}CupsPrinterList;
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;int ListLocalPrinters(CupsPrinterList **printerList=
);
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;int FreeLocalPrinterList(CupsPrinterList *listHead)=
;
    </DIV>
    <DIV>&nbsp;</DIV>
    <DIV>
      Wrapper code:
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;[ StructLayout(LayoutKind.Sequential) ]
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public struct PrinterList
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ MarshalAs(Unm=
anagedType.ByValTStr, SizeConst=3D1024) ]
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string =
printerUri;
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ MarshalAs(Unm=
anagedType.ByValTStr, SizeConst=3D1024) ]
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string =
printerCupsUri;
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ MarshalAs(Unm=
anagedType.ByValTStr, SizeConst=3D1024) ]
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string =
printerName;
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ MarshalAs(Unm=
anagedType.ByValTStr, SizeConst=3D256) ]
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string =
printerMakeModel;
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public IntPtr =
nextElement;
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;}
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;public class PrintLibWrapper
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;{
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ DllImport(&quot;print&quot;) ]
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern int =
ListLocalPrinters( ref PrinterList pl);
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;}
    </DIV>
    <DIV>&nbsp;</DIV>
    <DIV>
      Usage:
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;PrinterList printers =3D new PrinterList();
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;printers.nextElement =3D IntPtr.Zero;
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;int ccode =3D PrintLibWrapper.ListLocalPrinters(ref=
 printers);
    </DIV>
    <DIV>
      &nbsp;&nbsp;&nbsp;Console.WriteLine(&quot;printer name =3D &quot; + =
printers.printerName); // printers.printerName is empty
    </DIV>
    <DIV>&nbsp;</DIV>
    <DIV>
      I can successfully call ListLocalPrinters but unable to read even 1 =
result let alone iterate through the list. &nbsp;Seems I need another =
level of indirection (perhaps an IntPtr) when calling PrintLibWrapper.ListL=
ocalPrinters(). &nbsp;Didn't try this as I could not figure out how to =
describe &quot;unmarshalling&quot; of the returned data. &nbsp;&nbsp;Any =
pointers to additional info/examples would be appreciated. &nbsp;Was =
hoping to find an example in gtk-sharp (List.cs, ListBase.cs) but no =
marshalling of memory allocated by unmanaged code found there.
    </DIV>
    <DIV>&nbsp;</DIV>
    <DIV>
      Thanks.
    </DIV>
    <DIV>
      Jim
    </DIV>
  </body>
</html>

--=__PartFFDF8AE8.0__=--