[Mono-dev] Marshal Variable length structure Array in Mono
Jonathan Pryor
jonpryor at vt.edu
Tue Sep 6 07:26:29 EDT 2005
On Tue, 2005-09-06 at 12:50 +0200, Robert Jordan wrote:
> Indeed, variable length != variable count.
> But the returned structures must be manually marshaled:
>
> http://www.pinvoke.net/default.aspx/winspool.EnumPrinters
They're trying *way* too hard. This should work:
struct NativePrinterInfo2 {
public IntPtr pServerName;
public IntPtr pPrinterName;
/* ...
basically the PRINTER_INFO_2 struct with
IntPtr instead of string...
*/
}
[DllImport ("winspool")]
public static extern bool EnumPrinters (
uint Flags,
string Name,
uint Level,
[Out] NativePrinterInfo2[] pPrinterEnum,
uint cbBuf,
out uint pcbNeeded,
out uint pcReturned
);
Usage:
int printerInfoSize = Marshal.SizeOf (typeof(NativePrinterInfo2));
uint needed, returned;
if (!EnumPrinters (Flags, null, 2, null, 0, out needed,
out returned) {
throw new Exception ();
}
NativePrinterInfo2[] data =
new NativePrinterInfo2[returned/printerInfoSize];
if (!EnumPrinters (Flags, null, 2, data, returned,
out needed, out returned) {
throw new Exception ();
}
PRINTER_INFO_2[] printers = new PRINTER_INFO_2[data.Length];
for (int i = 0; i < printers.Length; ++i) {
printers [i].pServerName =
Marshal.PtrToStringAnsi (data [i].pServerName);
// ...
}
*Much* simpler than manually digging through a returned byte array like
they did...
Supporting the other PRINTER_INFO_* structures is as easy as overloading
EnumPrinters and doing the same thing with the other structures. Fairly
easy.
- Jon
More information about the Mono-devel-list
mailing list