如何解决如何获得有效的x64 THREADSAFE Ghostscript DLL
主要背景
我们实际上是在尝试获取Ghostscript x64 DLL的多线程版本,以通过Ghostscript .NET使用它。该组件应该“允许在单个进程中同时运行多个Ghostscript实例”,但是,正如我们在项目中所检查的那样,在向应用程序发出并发请求之前,它可以正常工作。可以使用Tasks复制相同的行为以启动相同的方法。在这两种情况下(仅当调用该过程直到执行最后一个过程时),才会出现错误描述:
调用“ gsapi_new_instance”时发生错误:-100
即使它似乎与.NET没有直接关系,我也将发布我们的C#方法代码示例,仅用于上下文化。
// Define switches...
string[] switchesArray = switches.ToArray();
using (GhostscriptProcessor procesador = new GhostscriptProcessor())
{
try
{
procesador.StartProcessing(switchesArray,null);
byte[] destinationFile = System.IO.File.ReadAllBytes(destinationPath);
return destinationFile;
}
catch (Exception ex)
{
throw ex;
}
finally
{
System.IO.File.Delete(sourceFile);
}
}
THREADSAFE解决方案
开始调查,我们在this post上找到了KenS的答案,表明必须使用GS_THREADSAFE编译器定义来生成Ghostscript DLL。
为澄清起见,当我们使用Ghostscript 9.52 x64生成PDF时,我们需要为Release配置编译此x64 DLL。在尝试使用Visual Studio Community 2017和Visual Studio Community 2019在Windows 10 x64计算机上编译Ghostscript源代码之后,我们最终设法在没有GS_THREADSAFE参数的情况下构建并生成了所有项目(仅使用VS Community 2019),只是为了确认编译是否正确,然后检查DLL和可执行文件是否正常运行。在此过程中,我们牢记在Ghostscript official documentation中找到的所有内容。
由于我们没有其他指南可以包含此GS_THREADSAFE参数,因此我们遵循了this solution中给出的说明,包括有关XCFLAGS="-DGS_THREADSAFE=1"
的nmake构建命令,请将该句子用于 Rebuild all 选项:
cd .. && nmake -f psi\msvc32.mak WIN64= SBR=1 DEVSTUDIO= XCFLAGS=-DGS_THREADSAFE=1 && nmake -f psi\msvc32.mak WIN64= DEVSTUDIO= XCFLAGS=-DGS_THREADSAFE=1 bsc
这种方法会在构建过程中引发错误:
在中引用的错误LNK2019无法解析的外部符号errprintf_nomem 函数gs_log_error文件\ mkromfs.obj 1
看起来,文件 mkromfs.c 具有名为 errprintf_nomem 的方法,设置GS_THREADSAFE时可以找到。
问题
1-Ghostscript是否有任何公开发布的版本,其中包含被编译为THREADSAFE的x64 DLL?
如果不是(那是我的猜测...)
2-是否可以在不更改源代码的情况下将此DLL设为THREADSAFE?
3-请问有人可以提供逐步指南或演练,以在Windows 10 x64上使用Visual Studio(甚至其他可能的替代方法)使用GS_THREADSAFE构建x64 Ghostscript DLL吗?
4-一些帖子谈到人们使用Ghostscript .NET可以管理多线程。我假设这些示例都使用GS_THREADSAFE DLL ...我们通过了其他解决方法吗?
非常感谢。
解决方法
好吧,在我看来,您正在这里寻求技术支持。
您显然想在商业活动中使用Ghostscript,确实有人可能会说您想要企业版Ghostscript。大概您不想为了允许使用开放源代码许可证而更改源代码,因为您不想为商业许可证付费。
请记住,您的问题的答案是:
- 不,Ghostscript开发人员实际上并不构建二进制文件的线程安全版本。
- 当前没有。这可能是疏忽。
- 那将是一个技术支持问题,不能保证免费用户会获得技术支持,这是双重许可证供应商说服人们购买商业许可证的少数几个方面之一。因此,我希望您能理解,我不会提供该功能。
- 据我所知,没有。
总结所有这些问题,并为以后遇到相同问题的开发人员提供指南,以下是我们迄今为止找到的答案:
-
AS @KenS在他的回复中提到:“不,Ghostscript开发人员实际上并未构建二进制的线程安全版本。”
-
这时,显然不是,this opened bug上已有报道。
-
由于这似乎是商业许可支持的问题,因此我们不再对此发表评论。
-
再次感谢@HABJAN。我绝对会收回我在问题上所说的内容,因为可以在多线程方案中使用Ghostscript .NET 。下面介绍了我们应用的解决方案,以防对某人有用。
基于HABJAN示例,我们为实现此目的而做的是创建一个自定义类来捕获Ghostscript日志记录:
protected class ConsoleStdIO : Ghostscript.NET.GhostscriptStdIO
{
public ConsoleStdIO(bool handleStdIn,bool handleStdOut,bool handleStdErr) : base(handleStdIn,handleStdOut,handleStdErr)
{
}
public override void StdIn(out string input,int count)
{
char[] userInput = new char[count];
Console.In.ReadBlock(userInput,count);
input = new string(userInput);
}
public override void StdOut(string output)
{
//log
}
public override void StdError(string error)
{
//log
}
}
对于先前的方法,我们简单地包含了对该类的调用,这样可以避免在同时执行多个任务时出错:
// Define switches...
string[] switchesArray = switches.ToArray();
using (GhostscriptProcessor procesador = new GhostscriptProcessor())
{
try
{
procesador.StartProcessing(switchesArray,new ConsoleStdIO(true,true,true));
byte[] destinationFile = System.IO.File.ReadAllBytes(destinationPath);
return destinationFile;
}
catch (Exception ex)
{
throw ex;
}
finally
{
System.IO.File.Delete(sourceFile);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。