powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
14 сообщений из 14, страница 1 из 1
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524076
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уже давно использую Ghostscript для напр. конвертации PDF->TIFF.
Один раз 5 лет назад скомпилировал GS 9.01, еще пару лет назад переписал Ghostscript API под .Net
Ну собственно кода там не шибко много
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
  '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 через произвольное к-во аргументов):
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    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:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
  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") == ВИСЯК.
И вот почему, что там не так может быть?

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


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

3. Ну и проблема с русско-китайским.
Декларация gsapi_init_with_args
Код: vbnet
1.
2.
3.
4.
  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


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


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


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

Я уж не говорю про более тяжелый случай (где в коде ? -там Z чешское с хвостом наверху)
Код: vbnet
1.
2.
3.
4.
  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 почему-то стало английским.
Код: vbnet
1.
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"
Код: vbnet
1.
Declare Unicode Function gsapi_init_with_args...

- это ничего не меняет.
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524079
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Странно, в коде GS есть такая фигня,
при этом то что между ifdef __WIN32__ и #endif типа серенькое (т.е. почему-то не было задействовано при компиляции). W и A при вызове "No entry points". А как включить, вроде итак на Win32 компилировал?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
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
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524117
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

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

А то чёт складывается ощущение, что ты просто охринеть как тащишься от всякого P/Invoke, маршаллинга и ковыряния по самые локти в WINAPI. Это что, такая адская форма садомазохизма? ))
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524324
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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-маршалинг
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  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 видимо дело вкуса.
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524415
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем с UTF8 прокатило:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
  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, но почему-то не фурычит.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
  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
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524501
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
жесть ))
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524535
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77А ты не в курсе, что 90% этих ".NET библиотек" и прочего софта используют Ghostscript?
Либо являются чем-то жалким и глючным.

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

Ну дело твоё конечно, я лишь выразил полное непонимание подобной упоротости. Видимо нравится, тут уже у кого какие так сказать нетрадиционные пристрастия.
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524536
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Просто чтобы сделать PDF -> Картинка (а не наоборот),
надо как бы полностью раскурочить его согласно спецификации PDF, а это не только текст и картинки.

Серьёзно?

https://mozilla.github.io/pdf.js/
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524537
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77И в данном случае это не "WIN" API, а API предоставляемые недетской такой библиотекой.

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

https://ru.wikipedia.org/wiki/Машина_Голдберга
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524542
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,

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

Ghostscript делает конкретно то что мне надо (даже не буду объяснять что именно, это в общем ясно из первого поста, да и вряд ли тебе это интересно, лиж бы запостить про какую-нибудь "какашку"), вряд ли твои библиотеки, работающие в браузере именно это умеют. М.б. и умеют, но вопрос про них не ставился в принципе.
Вопрос был чисто технический.
Задача описана, исходные данные и коды предоставлены.
Задача в целом решена, и заметь не тобой. И в общем-то за разумное время.
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524551
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Да ладно тебе бомбить. Пишешь на форум .NET про проблемы, не имеющие практически никакого отношения к .NET, предлагаешь молчать и спокойно наблюдать, как ты страдаешь фигнёй? :)
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524555
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
прекращай.

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

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

System.Text.Encoding.UTF8,
Marshal.AllocHGlobal
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.LPWStr)>
от которых напрямую зависит, прочтется ли Юникод или нет (вторая проблема),
это все не чисто .Net-овские штучки?
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524569
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77...100% CPU:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  '--- 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 нафиг не нужны, но хотелось разобраться.
Полезно иногда заглянуть во внутрь.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
/* 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:
Код: vbnet
1.
2.
3.
4.
5.
  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г.) счас проверил, содержит такую же точно фигню:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
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 , года два назад, утянул его целиком, в кишках не копался - отличная кстати вещь. Но: я до сих пор не отловил, почему у меня прога (оч. редко - можно забить) иногда да и может тупо скрашить, то что из-за риббон это точно, а отдебажить и понять не удалось, потому что это "коробка хренова", какая бы красивая она не была.
...
Рейтинг: 0 / 0
Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
    #39524570
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 причем мой аналогичный код VB6 (писал/слизывал в 2012г.) счас проверил, содержит такую же точно фигню:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
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 шары катить. Там как раз все корректно.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
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 ИМХО куда более грамотные люди писали, чем нынешние "оберточники".
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Ghostscript API 1) 100% CPU если вызывается Callback 2) Не понимает не-аглийские имена
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]