如何获得有效的x64 THREADSAFE Ghostscript DLL

如何解决如何获得有效的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。大概您不想为了允许使用开放源代码许可证而更改源代码,因为您不想为商业许可证付费。

请记住,您的问题的答案是:

  1. 不,Ghostscript开发人员实际上并不构建二进制文件的线程安全版本。
  2. 当前没有。这可能是疏忽。
  3. 那将是一个技术支持问题,不能保证免费用户会获得技术支持,这是双重许可证供应商说服人们购买商业许可证的少数几个方面之一。因此,我希望您能理解,我不会提供该功能。
  4. 据我所知,没有。
,

总结所有这些问题,并为以后遇到相同问题的开发人员提供指南,以下是我们迄今为止找到的答案:

  1. AS @KenS在他的回复中提到:“不,Ghostscript开发人员实际上并未构建二进制的线程安全版本。”

  2. 这时,显然不是,this opened bug上已有报道。

  3. 由于这似乎是商业许可支持的问题,因此我们不再对此发表评论。

  4. 再次感谢@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 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-