簡體   English   中英

如何獲得有效的 x64 THREADSAFE Ghostscript DLL

[英]How to get a working 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);
    }
}

線程安全解決方案

開始我們的調查,我們在這篇文章中找到了 KenS 的回答,表明必須使用 GS_THREADSAFE 編譯器定義生成 Ghostscript DLL。

澄清一下,當我們使用 Ghostscript 9.52 x64 來生成我們的 PDF 時,我們需要為發布配置編譯這個 x64 DLL。 在嘗試在 Windows 10 x64 機器上編譯 Ghostscript 源代碼后,使用 Visual Studio Community 2017 和 Visual Studio Community 2019,我們終於成功地構建和生成了所有項目(僅使用 VS Community 2019)而沒有 GS_THREADSAFE 參數,只是為了確認編譯沒問題,然后我們檢查 DLL 和可執行文件是否正常工作。 對於這個過程,我們考慮了我們在Ghostscript 官方文檔中找到的所有內容

由於我們沒有其他指南來包含此 GS_THREADSAFE 參數,因此我們按照此解決方案中給出的說明進行操作,包括 nmake 構建命令中的XCFLAGS="-DGS_THREADSAFE=1" ,將這句話用於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

這種方法在構建過程中出現錯誤:

函數 gs_log_error 文件 \\mkromfs.obj 1 中引用的錯誤 LNK2019 未解析的外部符號 errprintf_nomem

看起來,文件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. 在這一刻,顯然不是,因為它已經報告了這個打開的錯誤

  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, 0, 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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM