在Windows中将GhostScript 9.10与参数中的Unicode字符一起使用 [英] Using GhostScript 9.10 in Windows with Unicode characters in parameters
问题描述
我想在.NET/C#应用程序中使用Ghostscript将.tiff文件转换为PDF. 我的问题:当文件路径包含非ansi字符(例如Umlaute)时,函数
I want to use Ghostscript in a .NET / C# application to convert a .tiff file to PDF. My problem: When the file path contains non-ansi characters (e.g. Umlaute), the function
gsapi_init_with_args
失败. (对于GS 8.x,它可以正常工作!). 我发现有关该行为在9.x中已更改的信息,并且还找到了一个名为
fails. (With GS 8.x, it works fine!). I found information that the behaviour was changed in 9.x, and I also found a function called
gsapi_init_with_argsW
并且此函数应该可以与.NET一起使用,而不会出现任何问题(请参见 http ://permalink.gmane.org/gmane.comp.printing.ghostscript.cvs/31721 )
And this function should work with .NET without any problems (see http://permalink.gmane.org/gmane.comp.printing.ghostscript.cvs/31721)
所以我使用以下DLLImport:
So I use the following DLLImport:
[DllImport(@"gsdll32.dll")]
public static extern int gsapi_init_with_argsW( IntPtr instace, int argc, string[] argv);
但这仍然行不通,我收到错误消息:
but this still does not work, I get the error:
Error: /undefinedfilename
in (C:\\304NDERUNGEN\\TEST.PDF)
文件名称应为
C:\\ÄNDERUNGEN\\TEST.PDF
因此无法正确识别变音符号Ä".
so the umlaut "Ä" is not recognized correctly.
我在网上搜索了很多,但没有找到解决方法.
I´ve search the web a lot but did not found a solution.
有什么主意吗? 谢谢!
Any idea? Thank you!
推荐答案
我怀疑您需要在此处使用UTF-8.通过GS_ARG_ENCODING_UTF8
呼叫gs_set_arg_encoding
.
I suspect that you will need to use UTF-8 here. Make a call to gs_set_arg_encoding
passing GS_ARG_ENCODING_UTF8
.
任何传递给Ghostscript的字符串都应声明为IntPtr
.要将C#字符串转换为以空终止的UTF-8编码的字符串,请使用以下
Any strings that you pass to Ghostscript should be declared as IntPtr
. To convert from a C# string to a null-terminated UTF-8 encoded string use this function provided by Hans Passant:
public static IntPtr NativeUtf8FromString(string managedString)
{
int len = Encoding.UTF8.GetByteCount(managedString);
byte[] buffer = new byte[len + 1]; // null-terminator allocated
Encoding.UTF8.GetBytes(managedString, 0, managedString.Length, buffer, 0);
IntPtr nativeUtf8 = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, nativeUtf8, buffer.Length);
return nativeUtf8;
}
请确保您记得要通过调用Marshal.FreeHGlobal
进行清理.
Make sure that you remember to clean up with a call to Marshal.FreeHGlobal
.
整个代码可能看起来像这样:
The overall code might look a little like this:
public class Ghostscript
{
public const int GS_ARG_ENCODING_LOCAL = 0;
public const int GS_ARG_ENCODING_UTF8 = 1;
[DllImport("gsdll32.dll")]
private static extern int gsapi_new_instance(out IntPtr inst, IntPtr handle);
[DllImport("gsdll32.dll")]
private static extern int gsapi_set_arg_encoding(IntPtr inst, int encoding);
[DllImport("gsdll32.dll")]
private static extern int gsapi_init_with_args(IntPtr inst, int argc, IntPtr[] argv);
[DllImport("gsdll32.dll")]
private static extern int gsapi_exit(IntPtr inst);
[DllImport("gsdll32.dll")]
private static extern void gsapi_delete_instance(IntPtr inst);
private static void checkReturnValue(int retval)
{
if (retval != 0)
throw ...; // implement error handling here
}
public static void run(string[] argv)
{
IntPtr inst;
checkReturnValue(gsapi_new_instance(out inst, IntPtr.Zero));
try
{
IntPtr[] utf8argv = new IntPtr[argv.length];
for (int i=0; i<utf8argv.Length; i++)
utf8argv[i] = NativeUtf8FromString(argv[i]);
try
{
checkReturnValue(gsapi_set_arg_encoding(inst, GS_ARG_ENCODING_UTF8));
checkReturnValue(gsapi_init_with_args(inst, utf8argv.Length, utf8argv));
checkReturnValue(gsapi_exit(inst));
finally
{
for (int i=0; i<utf8argv.Length; i++)
Marshal.FreeHGlobal(utf8argv[i]);
}
}
finally
{
gsapi_delete_instance(inst);
}
}
}
这篇关于在Windows中将GhostScript 9.10与参数中的Unicode字符一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!