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

标签 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 exists? True
GLib.GException: Failed to open file 'C:\áéíóú.jpg': No such file or directory

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

最佳答案

这似乎是 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。因此,有缺陷的构造函数中的代码可以在某些辅助方法中进行复制、修复和隐藏,例如:

[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);
}

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

关于windows - 如何在 Windows 中从 Unicode 文件名创建 Gdk.Pixbuf?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12946991/

相关文章:

c# - .NET/C# 的线性编程库

c++ - 多处理和文件操作?

c++ - 在 std::string 中存储 unicode UTF-8 字符串

c++ - 日语系统上的字符转换不正确

c++ - 在 Qt 中,如何将 Unicode 代码点 U+1F64B 转换为包含等效字符 "🙋"的 QString?

Android 是使用 TableLayout 还是 GridView 更好

c# - Unity 的垃圾收集器——为什么是非分代和非压缩的?

c++ - CDHtmlDialog - 使其成为模式?

c++ - 如何获取桌面的窗口句柄?

windows - 在使用 native OpenSSH 的 ssh-agent 配置良好的 Windows 10 上,如何让 git 的实现使用配置的 ssh-agent?