Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4011
Уже давно использую Ghostscript для напр. конвертации PDF->TIFF.
Один раз 5 лет назад скомпилировал GS 9.01, еще пару лет назад переписал Ghostscript API под .Net
Ну собственно кода там не шибко много
+
  'GhostScript API
  Private Declare Function gsapi_revision Lib "gsdll32.dll" _
   (ByRef pGSRevisionInfo As GS_Revision, ByVal intLen As Integer) As Integer
  Private Declare Function gsapi_new_instance Lib "gsdll32.dll" _
   (ByRef lngGSInstance As IntPtr, ByVal lngCallerHandle As IntPtr) As Integer
  Private Declare Function gsapi_set_stdio Lib "gsdll32.dll" _
   (ByVal lngGSInstance As IntPtr, _
   ByVal gsdll_stdin As StdIOCallBack, _
   ByVal gsdll_stdout As StdIOCallBack, _
   ByVal gsdll_stderr As StdIOCallBack) As Integer
  Private Declare Function gsapi_init_with_args Lib "gsdll32.dll" _
   (ByVal lngGSInstance As IntPtr, ByVal lngArgumentCount As Integer, _
   <MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.LPStr)> _
   ByVal argv() As String) As Integer
  Private Declare Function gsapi_exit Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr) As Integer
  Private Declare Sub gsapi_delete_instance Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr)
  '------------------------------------------------
  'Callback Functions Start
  '------------------------------------------------
  'These are only required if you use gsapi_set_stdio

  '--- Delegate function for callbacks
  Private Delegate Function StdIOCallBack(ByVal handle As IntPtr, _
    ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer

  '--- Dummy callback for standard input, standard output, and errors
  Private Function InOutErrCallBack(ByVal handle As IntPtr, _
   ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer
    Debug.Print("Callback")
    Return 0
  End Function

  Public Function CallGS(ByVal ParamArray Args() As String) As Boolean
    Dim intReturn As Integer
    Dim intGSInstanceHandle As IntPtr
    Dim NumArgs As Integer
    Dim callerHandle As IntPtr
    Dim StdErrCallback As StdIOCallBack
    Dim StdInCallback As StdIOCallBack
    Dim StdOutCallback As StdIOCallBack

    StdInCallback = AddressOf InOutErrCallBack
    StdOutCallback = AddressOf InOutErrCallBack
    StdErrCallback = AddressOf InOutErrCallBack

    ' Load Ghostscript and get the instance handle
    intReturn = gsapi_new_instance(intGSInstanceHandle, callerHandle)
    If (intReturn < 0) Then
      Return False
    End If

    ' Capture stdio
    'intReturn = gsapi_set_stdio(intGSInstanceHandle, _
    ' StdInCallback, StdOutCallback, StdErrCallback)
    intReturn = gsapi_set_stdio(intGSInstanceHandle, _
     Nothing, Nothing, Nothing)
    If (intReturn >= 0) Then
      NumArgs = Args.Length

      '--- первый параметр игнорируется, но мы всегда его пишем (Ghostscript requirement)
      ReDim Preserve Args(NumArgs - 1)
      'System.Array.Copy(Args, 0, Args, 1, NumArgs)

      '--- Run Ghostscript using specified arguments
      intReturn = gsapi_init_with_args(intGSInstanceHandle, NumArgs, Args)

      ' Stop the Ghostscript interpreter
      intReturn = gsapi_exit(intGSInstanceHandle)
    End If

    ' release the Ghostscript instance handle
    gsapi_delete_instance(intGSInstanceHandle)

    If (intReturn >= 0) Then
      CallGS = True
    Else
      CallGS = False
    End If

  End Function


Вызывается примерно так (по сути передача командной строки GS через произвольное к-во аргументов):
    Call pdf2fax(IO.Path.Combine(Application.StartupPath, "input.pdf"), _
     IO.Path.Combine(Application.StartupPath, "output.tif"), "tiffg32d", "204x196")


  Public Sub pdf2fax(ByVal s_InputFile As String, ByVal s_OutputFile As String, _
   ByVal s_DEVICE As String, ByVal s_Resolution As String)
    Dim astrArgs(13) As String
    astrArgs(0) = "pdf2fax" 'The First Parameter is Ignored
    astrArgs(1) = "-q"
    astrArgs(2) = "-sDEVICE=" & s_DEVICE '"-sDEVICE=tiffg32d"
    astrArgs(3) = "-r" & s_Resolution '"-r204x98"
    astrArgs(4) = "-dAdjustWidth=1" 'иначе не делает 1728 для lzw/packbits
    astrArgs(5) = "-dBATCH"
    astrArgs(6) = "-dPDFFitPage"
    astrArgs(7) = "-dNOPAUSE"
    astrArgs(8) = "-dFillOrder=2"
    astrArgs(9) = "-sOutputFile=" & s_OutputFile
    astrArgs(10) = "-f"
    astrArgs(11) = s_InputFile
    astrArgs(12) = "-c"
    astrArgs(13) = "quit"
    Try : CallGS(astrArgs) : Catch : End Try
  End Sub


Все бы хорошо, но изредка жалобы, типа какой-то гадский (оч. редко) PDF не конвертируется, более того ф-ция CallGS (gsapi_init_with_args) мертво виснет + еще 100% CPU. Прогу естественно это выводит из строя, пока юзер не догадается убить процесс.

Гадских PDF наколлекционировал штук несколько (от юзеров). Стал наконец разбираться.

1. Для начала скомпилировал GS 9.21 Last Version в VC++2005 (5 лет все же прошло). Ну удалось тьфу-тьфу, слава богу его консерваторы пишут, хотя SDK в msvc.mak пришлось таки комментировать/подправлять.
Проблему с несколькими (не со всеми) файлами это решило, с другими все равно через API hanging (хотя gswin32c.exe -штатная - с ними справляется, хотя и информирует о каких-то ошибках).

2. Нашел причину 100% CPU:
  Private Declare Function gsapi_set_stdio Lib "gsdll32.dll" _
   (ByVal lngGSInstance As IntPtr, _
   ByVal gsdll_stdin As StdIOCallBack, _
   ByVal gsdll_stdout As StdIOCallBack, _
   ByVal gsdll_stderr As StdIOCallBack) As Integer

  '--- Delegate function for callbacks
  Private Delegate Function StdIOCallBack(ByVal handle As IntPtr, _
    ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer

  '--- Dummy callback for standard input, standard output, and errors
  Private Function InOutErrCallBack(ByVal handle As IntPtr, _
   ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer
    Debug.Print("Callback")
    Return 0
  End Function
 
...
    Dim StdErrCallback As StdIOCallBack
    Dim StdInCallback As StdIOCallBack
    Dim StdOutCallback As StdIOCallBack

    StdInCallback = AddressOf InOutErrCallBack
    StdOutCallback = AddressOf InOutErrCallBack
    StdErrCallback = AddressOf InOutErrCallBack

   ' Capture stdio
    intReturn = gsapi_set_stdio(intGSInstanceHandle, _
     StdInCallback, StdOutCallback, StdErrCallback)

В общем когда эта тварь выводит любое сообщение об ошибке (обычно просто предупреждение что в pdf файле что-то не по спецификации), оно стучится в InOutErrCallBack.
Слово Debug.Print("Callback") == ВИСЯК.
И вот почему, что там не так может быть?

Полечил достаточно просто:
    intReturn = gsapi_set_stdio(intGSInstanceHandle, _
     Nothing, Nothing, Nothing)

(теперь во всяком случае при запуске из студии весь output - мусор сыпется в "Вывод", конвертация работает)
А с другой стороны весь этот output - бред про какой-то не тот тег в pdf нафиг не нужен, файл конвертирует, не виснет при этом и ладно.
Нормальное решение?

3. Ну и проблема с русско-китайским.
Декларация gsapi_init_with_args
  Private Declare Function gsapi_init_with_args Lib "gsdll32.dll" _
   (ByVal lngGSInstance As IntPtr, ByVal lngArgumentCount As Integer, _
   <MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.LPStr)> _
   ByVal argv() As String) As Integer

(я вот не знаю насколько она в принципе "юникодная")
Но если я пытаюсь сделать хотя бы так (это при том что у меня на компе установлен "русский для НЕ-Юникод программ")
    Call pdf2fax(IO.Path.Combine(Application.StartupPath, "Привет.pdf"), _
     IO.Path.Combine(Application.StartupPath, "hello.tif"), "tiffg32d", "204x196")

монстро вываливает в Debug буквально следующее.
Error: /undefinedfilename in (C:\\Setup\\ghostscript\\TestGSAPI\\TestGSAPI\\bin\\Debug\\\317\360\350\342\345\362.pdf)

(файл Привет естесвенно по этому пути имеется)

Я уж не говорю про более тяжелый случай (где в коде ? -там Z чешское с хвостом наверху)
  Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
    Call pdf2fax(IO.Path.Combine(Application.StartupPath, "Davorka &#381;imbrek - Sd.pdf"), _
     IO.Path.Combine(Application.StartupPath, "davorka.tif"), "tiffg32d", "204x196")
  End Sub
т.е. чешское Z почему-то стало английским.
Error: /undefinedfilename in (C:\\Setup\\ghostscript\\TestGSAPI\\TestGSAPI\\bin\\Debug\\Davorka Zimbrek - Sd.pdf)

Реально ли с этим побороться?
М.б. маршалинг как-то по другому прописать?

Коды GS как -бы открыты, компилировал сам , да и проект GS скорее всего юникодный.
Ихнее gswin32c.exe (по крайней мере в крайней v.9.21) этого Davorka Zimbrek с иероглифом над Z сжирает, с "Привет" тоже проблем нет. Куда бы покопать?
В идеале конечно хотелось бы аналог "W"
Declare Unicode Function gsapi_init_with_args...
- это ничего не меняет.
21 сен 17, 05:30    [20810754]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4011
Странно, в коде GS есть такая фигня,
при этом то что между ifdef __WIN32__ и #endif типа серенькое (т.е. почему-то не было задействовано при компиляции). W и A при вызове "No entry points". А как включить, вроде итак на Win32 компилировал?

GSDLLEXPORT int GSDLLAPI gsapi_init_with_args(void *instance,
    int argc, char **argv);

#ifdef __WIN32__
GSDLLEXPORT int GSDLLAPI gsapi_init_with_argsA(void *instance,
    int argc, char **argv);

GSDLLEXPORT int GSDLLAPI gsapi_init_with_argsW(void *instance,
    int argc, wchar_t **argv);
#endif
21 сен 17, 05:53    [20810757]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
hVostt
Member

Откуда:
Сообщений: 11352
Дмитрий77,

НЕ думал смотреть в сторону .NET библиотек для работы с PDF?

А то чёт складывается ощущение, что ты просто охринеть как тащишься от всякого P/Invoke, маршаллинга и ковыряния по самые локти в WINAPI. Это что, такая адская форма садомазохизма? ))
21 сен 17, 09:12    [20810945]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4011
hVostt
НЕ думал смотреть в сторону .NET библиотек для работы с PDF?

А ты не в курсе, что 90% этих ".NET библиотек" и прочего софта используют Ghostscript?
Либо являются чем-то жалким и глючным.
(ну естественно еще Adobe софт)
Просто чтобы сделать PDF -> Картинка (а не наоборот),
надо как бы полностью раскурочить его согласно спецификации PDF, а это не только текст и картинки.

hVostt
по самые локти в WINAPI. Это что, такая адская форма садомазохизма? ))

Ну, садомазохизма в этом простеньком коде, что уместился под спойлером в первом посте не особо много.
И в данном случае это не "WIN" API, а API предоставляемые недетской такой библиотекой.
https://www.ghostscript.com/doc/current/API.htm

Вот вроде нарыл пока по теме
Using GhostScript 9.10 in Windows with Unicode characters in parameters
но пока особо не врубался.

Попробовал на дурака вот так присобачить Unicode-маршалинг
  Private Const GS_ARG_ENCODING_UTF16LE As Integer = 2

  Private Declare Function gsapi_set_arg_encoding Lib "gsdll32.dll" _
   (ByVal lngGSInstance As IntPtr, _
   ByVal encoding As Integer) As Integer
  Private Declare Unicode Function gsapi_init_with_args Lib "gsdll32.dll" _
   (ByVal lngGSInstance As IntPtr, ByVal lngArgumentCount As Integer, _
   <MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.LPWStr)> _
   ByVal argv() As String) As Integer

   intReturn = gsapi_set_arg_encoding(intGSInstanceHandle, GS_ARG_ENCODING_UTF16LE)
      intReturn = gsapi_init_with_args(intGSInstanceHandle, NumArgs, Args)

но не прокатило, перестал понимать англицкий.
Видимо придется таки впихивать строки в массив указателей как там, с последующим освобождением
Marshal.AllocHGlobal/Marshal.FreeHGlobal,
(хотя лучше б без этого)
ну а utf-8/utf-16==Unicode видимо дело вкуса.
21 сен 17, 13:19    [20812035]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4011
В общем с UTF8 прокатило:
  Private Declare Function gsapi_set_arg_encoding Lib "gsdll32.dll" _
   (ByVal lngGSInstance As IntPtr, _
   ByVal encoding As Integer) As Integer
  Private Declare Function gsapi_init_with_args Lib "gsdll32.dll" _
   (ByVal lngGSInstance As IntPtr, ByVal lngArgumentCount As Integer, _
   ByVal argv() As IntPtr) As Integer

  Private Const GS_ARG_ENCODING_UTF8 As Integer = 1

  Public Sub CallGS(ByVal ParamArray Args() As String)
    If IsNothing(Args) Then Exit Sub

    Dim intReturn As Integer
    Dim intGSInstanceHandle As IntPtr
    'Dim NumArgs As Integer
    Dim callerHandle As IntPtr

    ' Load Ghostscript and get the instance handle
    intReturn = gsapi_new_instance(intGSInstanceHandle, callerHandle)
    If intReturn < 0 Then Exit Sub

    intReturn = gsapi_set_arg_encoding(intGSInstanceHandle, GS_ARG_ENCODING_UTF8)

    Dim utf8argv As IntPtr()
    ReDim utf8argv(0 To UBound(Args))
    For i As Integer = 0 To UBound(utf8argv)
      Dim buffer As Byte()
      ReDim buffer(0 To System.Text.Encoding.UTF8.GetByteCount(Args(i))) ' null-terminator allocated
      System.Text.Encoding.UTF8.GetBytes(Args(i), 0, Strings.Len(Args(i)), buffer, 0)
      utf8argv(i) = Marshal.AllocHGlobal(UBound(buffer) + 1)
      Marshal.Copy(buffer, 0, utf8argv(i), UBound(buffer) + 1)
    Next

    '--- Run Ghostscript using specified arguments
    intReturn = gsapi_init_with_args(intGSInstanceHandle, UBound(Args), utf8argv)

    For i As Integer = 0 To UBound(utf8argv)
      Marshal.FreeHGlobal(utf8argv(i))
    Next

    ' Stop the Ghostscript interpreter
    intReturn = gsapi_exit(intGSInstanceHandle)

    ' release the Ghostscript instance handle
    gsapi_delete_instance(intGSInstanceHandle)
  End Sub

Заодно убрал про Callback-и, и переделал Function в Sub - нафиг эти тупые проверки, файл появился, значит True.
Всему виной - хапнул чужой код когда-то не глядя, вот он: Simple VB.Net Wrapper for Ghostscript Dll
Работать то он работал, но изредка плодил проблемы с висяками.
Съедает теперь и "Приветы", и чешские Z, и "PDF слегка не по specification"
Смущает заочно, т.к. у меня все работает - не нарвался на это(в комментарии здесь).
автор
The original problem was solved, but now I get on some machines an AccessViolationException. Do you have any idea?


Ну и почему-то не работает по аналогии Unicode==UTF16, хотя по документации типа должен.
Собственно неработоспособность кода ниже объясняет, почему не получилось со стандартным Unicode-маршалингом (как с Win "W"-API) в конце предыдущего поста (для UTF-8 подобного механизма вроде нет).
А обидно, UTF16LE это по идее Little Endian == Unicode, но почему-то не фурычит.

  Private Const GS_ARG_ENCODING_UTF16LE As Integer = 2

  Public Sub CallGS(ByVal ParamArray Args() As String)
    If IsNothing(Args) Then Exit Sub

    Dim intReturn As Integer
    Dim intGSInstanceHandle As IntPtr
    'Dim NumArgs As Integer
    Dim callerHandle As IntPtr

    ' Load Ghostscript and get the instance handle
    intReturn = gsapi_new_instance(intGSInstanceHandle, callerHandle)
    If intReturn < 0 Then Exit Sub

    intReturn = gsapi_set_arg_encoding(intGSInstanceHandle, GS_ARG_ENCODING_UTF16LE)

    Dim utf16argv As IntPtr()
    ReDim utf16argv(0 To UBound(Args))
    For i As Integer = 0 To UBound(utf16argv)
      Dim buffer As Byte()
      ReDim buffer(0 To System.Text.Encoding.Unicode.GetByteCount(Args(i))) ' null-terminator allocated
      System.Text.Encoding.Unicode.GetBytes(Args(i), 0, Strings.Len(Args(i)), buffer, 0)
      utf16argv(i) = Marshal.AllocHGlobal(UBound(buffer) + 1)
      Marshal.Copy(buffer, 0, utf16argv(i), UBound(buffer) + 1)
    Next

    '--- Run Ghostscript using specified arguments
    intReturn = gsapi_init_with_args(intGSInstanceHandle, UBound(Args), utf16argv)

    For i As Integer = 0 To UBound(utf16argv)
      Marshal.FreeHGlobal(utf16argv(i))
    Next

    ' Stop the Ghostscript interpreter
    intReturn = gsapi_exit(intGSInstanceHandle)

    ' release the Ghostscript instance handle
    gsapi_delete_instance(intGSInstanceHandle)
  End Sub
21 сен 17, 15:40    [20812784]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Pallaris
Member

Откуда: Украина, Донецк
Сообщений: 1565
жесть ))
21 сен 17, 18:53    [20813434]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
hVostt
Member

Откуда:
Сообщений: 11352
Дмитрий77
А ты не в курсе, что 90% этих ".NET библиотек" и прочего софта используют Ghostscript?
Либо являются чем-то жалким и глючным.


Я уж не знаю чего ты там куришь... Кому нахрен упало это говно мамонта? Сегодня PDF рендерится даже на страницах в браузере средствами JavaScript, на .NET уже давным давно есть чистые дотнетовские либы, которые работают изумительно.

Ну дело твоё конечно, я лишь выразил полное непонимание подобной упоротости. Видимо нравится, тут уже у кого какие так сказать нетрадиционные пристрастия.
21 сен 17, 21:51    [20813803]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
hVostt
Member

Откуда:
Сообщений: 11352
Дмитрий77
Просто чтобы сделать PDF -> Картинка (а не наоборот),
надо как бы полностью раскурочить его согласно спецификации PDF, а это не только текст и картинки.


Серьёзно?

https://mozilla.github.io/pdf.js/
21 сен 17, 21:53    [20813809]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
hVostt
Member

Откуда:
Сообщений: 11352
Дмитрий77
И в данном случае это не "WIN" API, а API предоставляемые недетской такой библиотекой.


Да уж, главное всё максимально усложнить, надеюсь за простейшие вещи, которые ты решаешь путём анального ректалиуса, тебе хотя бы нормально платят :)

https://ru.wikipedia.org/wiki/Машина_Голдберга
21 сен 17, 21:56    [20813821]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4011
hVostt,

Ты зачем лезешь в тему если нечего сказать по сути или не рубишь то о чем спрашивают?
Иди в курилку и трепись там про "говно мамонта" сколько влезет (не со мной).

Ghostscript делает конкретно то что мне надо (даже не буду объяснять что именно, это в общем ясно из первого поста, да и вряд ли тебе это интересно, лиж бы запостить про какую-нибудь "какашку"), вряд ли твои библиотеки, работающие в браузере именно это умеют. М.б. и умеют, но вопрос про них не ставился в принципе.
Вопрос был чисто технический.
Задача описана, исходные данные и коды предоставлены.
Задача в целом решена, и заметь не тобой. И в общем-то за разумное время.
21 сен 17, 22:21    [20813904]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
hVostt
Member

Откуда:
Сообщений: 11352
Дмитрий77,

Да ладно тебе бомбить. Пишешь на форум .NET про проблемы, не имеющие практически никакого отношения к .NET, предлагаешь молчать и спокойно наблюдать, как ты страдаешь фигнёй? :)
21 сен 17, 23:21    [20814064]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4011
hVostt,
прекращай.

Я пишу на VB.Net (это не .Net Framework?), более того в WinForms.
А вопросы, они могут быть любые.
И ответы если они даются должны быть адекватны вопросам, а не бла-бла гавно мамонта.

Delegate, из-за которого висяк + 100% CPU (первая проблема) -это не .Net?

System.Text.Encoding.UTF8,
Marshal.AllocHGlobal
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.LPWStr)>
от которых напрямую зависит, прочтется ли Юникод или нет (вторая проблема),
это все не чисто .Net-овские штучки?
21 сен 17, 23:36    [20814093]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4011
Дмитрий77
...100% CPU:
  '--- Delegate function for callbacks
  Private Delegate Function StdIOCallBack(ByVal handle As IntPtr, _
    ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer

  '--- Dummy callback for standard input, standard output, and errors
  Private Function InOutErrCallBack(ByVal handle As IntPtr, _
   ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer
    Debug.Print("Callback")
    Return 0
  End Function

В общем когда эта тварь выводит любое сообщение об ошибке (обычно просто предупреждение что в pdf файле что-то не по спецификации), оно стучится в InOutErrCallBack.
Слово Debug.Print("Callback") == ВИСЯК.
И вот почему, что там не так может быть?

В принципе мне эти CallBack нафиг не нужны, но хотелось разобраться.
Полезно иногда заглянуть во внутрь.
/* Set the callback functions for stdio
 * The stdin callback function should return the number of
 * characters read, 0 for EOF, or -1 for error.
 * The stdout and stderr callback functions should return
 * the number of characters written.
 * If a callback address is NULL, the real stdio will be used.
 */
GSDLLEXPORT int GSDLLAPI
gsapi_set_stdio(void *instance,
    int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len),
    int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len),
    int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len));

Не уверен про stdin,
но stdout и stderr должны возвращать не 0, а "the number of characters written", т.е. строго 3-й параметр.
Вот хотя бы так все OK:
  Private Function InOutErrCallBack(ByVal handle As IntPtr, _
   ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer
    Debug.Print(Marshal.PtrToStringAnsi(Strz, Bytes))
    Return Bytes
  End Function

А ошибка зараза пришла из упомянутого места Simple VB.Net Wrapper for Ghostscript Dll (статья 2013г, воспользовался в 2015), причем мой аналогичный код VB6 (писал/слизывал в 2012г.) счас проверил, содержит такую же точно фигню:
Public Function gsdll_stdin _
 (ByVal intGSInstanceHandle As Long, ByVal StrZ As Long, ByVal intBytes As Long) As Long
  ' We don't have a console, so just return EOF
  gsdll_stdin = 0
End Function

Public Function gsdll_stderr(ByVal intGSInstanceHandle As Long, ByVal StrZ As Long, ByVal intBytes As Long) As Long
  gsdll_stderr = gsdll_stdout(intGSInstanceHandle, StrZ, intBytes)
End Function
Это называется, тырим баги друг у друга. "Авторы" очевидно не нарывались. Спрашивается, зачем их вообще рисовать (для красоты кодинга?) если "We don't have a console, so just return..." Этот безобидный "just return" и вызывает "just hangs with 100% CPU". Всё.

hVostt
НЕ думал смотреть в сторону .NET библиотек ... такая адская форма садомазохизма? ))

Угу-угу.
Ghostscript.NET (written in C#)
Типичная адская форма .Net-овского садомазохизма.
Я из подобного проджекта pop3/imap выковыривал, кстати успешно.
Но к слову я думаю этот как раз грамотно написан и без багов типа возврат нуля абы шо-бы. Только в таких проектах обычно 98% -лишний мне нафиг не нужный мусор.
И, не было этого проекта в 2012г. когда я VB6 писал, а когда мигрировал на .Net, не до тонкостей было (оч. много всего).

А взять просто чью-то .Net dll, чо сказать. Такой баг (типа описанного здесь) если аффтор бальшой абертки его су*а случайно заложил в свою dll, фиг отловишь. Я воспользовался Windows Ribbon for WinForms, года два назад, утянул его целиком, в кишках не копался - отличная кстати вещь. Но: я до сих пор не отловил, почему у меня прога (оч. редко - можно забить) иногда да и может тупо скрашить, то что из-за риббон это точно, а отдебажить и понять не удалось, потому что это "коробка хренова", какая бы красивая она не была.
22 сен 17, 03:08    [20814256]     Ответить | Цитировать Сообщить модератору
 Re: Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4011
Дмитрий77
причем мой аналогичный код VB6 (писал/слизывал в 2012г.) счас проверил, содержит такую же точно фигню:
Public Function gsdll_stdin _
 (ByVal intGSInstanceHandle As Long, ByVal StrZ As Long, ByVal intBytes As Long) As Long
  ' We don't have a console, so just return EOF
  gsdll_stdin = 0
End Function

Public Function gsdll_stderr(ByVal intGSInstanceHandle As Long, ByVal StrZ As Long, ByVal intBytes As Long) As Long
  gsdll_stderr = gsdll_stdout(intGSInstanceHandle, StrZ, intBytes)
End Function
Это называется, тырим баги друг у друга. "Авторы" очевидно не нарывались. Спрашивается, зачем их вообще рисовать (для красоты кодинга?) если "We don't have a console, so just return..." Этот безобидный "just return" и вызывает "just hangs with 100% CPU".

А не, это я погорячился на VB6 шары катить. Там как раз все корректно.
Public Function gsdll_stdin _
 (ByVal intGSInstanceHandle As Long, ByVal StrZ As Long, ByVal intBytes As Long) As Long
  ' We don't have a console, so just return EOF
  gsdll_stdin = 0
End Function

Public Function gsdll_stdout _
 (ByVal intGSInstanceHandle As Long, ByVal StrZ As Long, ByVal intBytes As Long) As Long
  ' If you can think of a more efficient method, please tell me!
  ' We need to convert from a byte buffer to a string
  ' First we create a byte array of the appropriate size
  Dim aByte() As Byte
  ReDim aByte(intBytes)
  ' Then we get the address of the byte array
  Dim ptrByte As Long
  ptrByte = VarPtr(aByte(0))
  ' Then we copy the buffer to the byte array
  CopyMemory ptrByte, StrZ, intBytes
  ' Then we copy the byte array to a string, character by character
  Dim str As String
  Dim i As Long
  For i = 0 To intBytes - 1
    str = str + Chr(aByte(i))
  Next
  ' Finally we output the message
  Debug.Print (str)
  'MsgBox (str)
  gsdll_stdout = intBytes
End Function

Public Function gsdll_stderr(ByVal intGSInstanceHandle As Long, ByVal StrZ As Long, ByVal intBytes As Long) As Long
  gsdll_stderr = gsdll_stdout(intGSInstanceHandle, StrZ, intBytes)
End Function
Там как раз 3-й параметр возвращается как положено.
На VB6 ИМХО куда более грамотные люди писали, чем нынешние "оберточники".
22 сен 17, 04:00    [20814260]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить