如何在Windows中从Unicode文件名创建Gdk.Pixbuf?

时间:2012-10-18 04:13:01

标签: windows unicode mono gtk filenames

我有一个C#/ Mono / Gtk#程序,只需将窗口中丢弃的文件加载为Gdk.Pixbuf并显示它们。

它在Ubuntu上运行良好。但是在Windows上,如果我尝试删除具有非ASCII文件名的文件,例如C:\áéíóú.jpg,程序将崩溃。我认为我的代码首先出现问题。所以我做了一个简单的测试用例。

Console.WriteLine("{0} exists? {1}", Filename, File.Exists(Filename));
Pixbuf pixels = new Pixbuf (Filename)

输出

  

C:\áéíóú.jpg存在吗?真
  GLib.GException:无法打开文件'C:\áéíóú.jpg':没有这样的文件或目录

事实证明,Glib无法找出存在的文件。而且我不知道如何修复它以便我可以从Unicode文件名中将图像文件加载到Windows上的Pixbuf中。

1 个答案:

答案 0 :(得分:2)

这似乎是gtk-sharp< - > gdk-pixbuf互操作中的一个问题。

显然在除Windows之外的每个操作系统上,gdk_pixbuf_new_from_file都采用utf8编码的文件名。但是,在Windows上,此函数重命名为gdk_pixbuf_new_from_file_utf8,并由执行语言环境转换的包装器替换,并继续调用utf8版本。 gtk-sharp不知道这个并使用gdk_pixbuf_new_from_file传递utf8参数,因此Windows上意外的额外语言环境转换会破坏文件名。

作为一种解决方法,我建议使用Pixbuf构造函数,该构造函数采用Stream而不是文件名,但海报报告说它没有正确加载图像。

<强>更新 幸运的是,Pixbuf包装器类有一个构造函数,它接受现有pixbuf对象的原始IntPtr。因此,buggy构造函数中的代码可以复制,修复和隐藏在一些帮助方法中,例如:

[DllImport("libgdk_pixbuf-2.0-0.dll")]
static extern IntPtr gdk_pixbuf_new_from_file_utf8(IntPtr filename, out IntPtr error);

static Pixbuf CreatePixbufWin32(string filename)
{
    IntPtr native_filename = GLib.Marshaller.StringToPtrGStrdup(filename);
    IntPtr error = IntPtr.Zero;
    IntPtr raw = gdk_pixbuf_new_from_file_utf8(native_filename, out error);
    GLib.Marshaller.Free(native_filename);
    if (error != IntPtr.Zero) throw new GLib.GException(error);
    return new Pixbuf(raw);
}

static Pixbuf CreatePixbuf(string filename)
{
    if (Environment.OSVersion.Platform == PlatformID.Win32NT)
    {
        return CreatePixbufWin32(filename);
    }
    return new Pixbuf(filename);
}

我已成功测试了这一点。希望这会有所帮助。