我有一个C#/ Mono / Gtk#程序,简单地加载文件作为Gdk.Pixbuf下载并显示它们。
它在Ubuntu上运行良好。 但在Windows上,如果我尝试使用非ASCII文件名(例如C:\áéíóú.jpg)删除文件,程序将会崩溃。 我认为这是我的代码第一个问题。 所以我做了一个简单的testing用例。
Console.WriteLine("{0} exists? {1}", Filename, File.Exists(Filename)); Pixbuf pixels = new Pixbuf (Filename)
产量
C:\áéíóú.jpg存在吗? 真正
GLib.GException:无法打开文件“C:\áéíóú.jpg”:没有这样的文件或目录
事实certificate,Glib无法找出存在的文件。 我不知道如何解决这个问题,这样我就可以从一个Unicode文件名中将一个图像文件加载到Windows上的Pixbuf中。
这似乎是gtk-sharp gdk-pixbuf互操作中的一个问题。
显然,除了windows以外的每个操作系统, gdk_pixbuf_new_from_file
都是以utf8编码的文件名。 然而,在Windows上,这个函数被重命名为gdk_pixbuf_new_from_file_utf8
,并被一个包含locale转换的包装所代替,并继续调用utf8版本。 gtk-sharp不知道这一点,并使用gdk_pixbuf_new_from_file
传递utf8参数,因此在Windows上意外的额外语言环境转换会破坏文件名。
作为一种解决方法,我建议使用Pixbuf
构造函数来获取Stream
而不是文件名,但是海报已经报告不能正确载入他的图像。
更新:幸运的是,Pixbuf包装类有一个构造函数接受现有pixbuf对象的原始IntPtr。 同样的,在bug的构造函数中的代码可以被复制,固定和隐藏在一些辅助方法中,比如:
[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); }
我已经测试成功。 希望这可以帮助。