public IEnumerable <Out123.Driver> Drivers() { IntPtr namesPtr = Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>()); IntPtr descsPtr = Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>()); Out123.Errors error = Out123NativeMethods.Drivers(handle, namesPtr, descsPtr); if (error != Out123.Errors.OK) { Marshal.FreeHGlobal(namesPtr); Marshal.FreeHGlobal(descsPtr); throw new Out123.ErrorException(this); } IntPtr namesPtrDeref = Marshal.ReadIntPtr(namesPtr); IntPtr descsPtrDeref = Marshal.ReadIntPtr(descsPtr); int offset = 0; while (true) { IntPtr namePtr = Marshal.ReadIntPtr(namesPtrDeref, offset); IntPtr descPtr = Marshal.ReadIntPtr(descsPtrDeref, offset); if (namePtr == IntPtr.Zero) { yield break; } String name = Marshal.PtrToStringAnsi(namePtr); String desc = Marshal.PtrToStringAnsi(descPtr); Out123.Driver driver = new Out123.Driver(name, desc); yield return(driver); offset += Marshal.SizeOf <IntPtr>(); } }