diff --git a/Source/OpenTK/Audio/OpenAL/Alc/Alc.cs b/Source/OpenTK/Audio/OpenAL/Alc/Alc.cs
index 38767a15..371bd81f 100644
--- a/Source/OpenTK/Audio/OpenAL/Alc/Alc.cs
+++ b/Source/OpenTK/Audio/OpenAL/Alc/Alc.cs
@@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;
@@ -262,7 +263,13 @@ namespace OpenTK.Audio.OpenAL
/// A string containing the name of the Device.
public static string GetString(IntPtr device, AlcGetString param)
{
- return Marshal.PtrToStringAnsi(GetStringPrivate(device, param));
+ IntPtr pstr = GetStringPrivate(device, param);
+ string str = String.Empty;
+ if (pstr != IntPtr.Zero)
+ {
+ str = Marshal.PtrToStringAnsi(pstr);
+ }
+ return str;
}
/// This function returns a List of strings related to the context.
@@ -277,26 +284,54 @@ namespace OpenTK.Audio.OpenAL
public static IList GetString(IntPtr device, AlcGetStringList param)
{
List result = new List();
- IntPtr t = GetStringPrivate(IntPtr.Zero, (AlcGetString)param);
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
- byte b;
- int offset = 0;
- do
- {
- b = Marshal.ReadByte(t, offset++);
- if (b != 0)
- sb.Append((char)b);
- if (b == 0)
- {
- result.Add(sb.ToString());
- if (Marshal.ReadByte(t, offset) == 0) // offset already properly increased through ++
- break; // 2x null
- else
- sb.Remove(0, sb.Length); // 1x null
- }
- } while (true);
- return (IList)result;
+ // We cannot use Marshal.PtrToStringAnsi(),
+ // because alcGetString is defined to return either a nul-terminated string,
+ // or an array of nul-terminated strings terminated by an extra nul.
+ // Marshal.PtrToStringAnsi() will fail in the latter case (it will only
+ // return the very first string in the array.)
+ // We'll have to marshal this ourselves.
+ IntPtr t = GetStringPrivate(device, (AlcGetString)param);
+ if (t != IntPtr.Zero)
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ byte b;
+ int offset = 0;
+ do
+ {
+ b = Marshal.ReadByte(t, offset++);
+ if (b != 0)
+ {
+ sb.Append((char)b);
+ }
+ else
+ {
+ // One string from the array is complete
+ result.Add(sb.ToString());
+
+ // Check whether the array has finished
+ // Note: offset already been increased through offset++ above
+ if (Marshal.ReadByte(t, offset) == 0)
+ {
+ // 2x consecutive nuls, we've read the whole array
+ break;
+ }
+ else
+ {
+ // Another string is starting, clear the StringBuilder
+ sb.Remove(0, sb.Length);
+ }
+ }
+ }
+ while (true);
+ }
+ else
+ {
+ Debug.Print("[Audio] Alc.GetString({0}, {1}) returned null.",
+ device, param);
+ }
+
+ return result;
}
[DllImport(Alc.Lib, EntryPoint = "alcGetIntegerv", ExactSpelling = true, CallingConvention = Alc.Style, CharSet = CharSet.Ansi), SuppressUnmanagedCodeSecurity()]