Конференция "KOL" » Problem with LoadLibrary
 
  • Jon © (17.10.07 17:44) [0]
    I have a problem using the Ghostscript API in my KOL application.

    The process works correctly on the first iteration of the loop, but memory is corrupted in subsequent operations.

    Here is a simplified demonstration of the problem:


    program Test;

    uses
     Windows, KOL;

    var
     Button, FileList: PControl;

    procedure ProcessPDF(PDFFileName, ImageFileName: String);
    var
     libGSdll: HMODULE;
     GSinstance: Pointer;
     ErrorCode: Integer;
     Args: array of PChar;
     gsapi_new_instance: function (pinstance: Pointer; caller_handle: Pointer): Integer; stdcall;
     gsapi_init_with_args: function (pinstance:Pointer; argc: Integer; argv: array of PChar): Integer; stdcall;
     gsapi_exit: function (pinstance: Pointer): Integer; stdcall;
     gsapi_delete_instance: procedure (pinstance: Pointer); stdcall;
    begin
     MsgOK('Source = ' + PDFFileName + #$0D#$0A + 'Destination = ' + ImageFileName);
     if FileExists(PDFFileName) then
     begin
       libGSdll := LoadLibrary(PChar('c:\Program Files\gs\gs8.60\bin\gsdll32.dll'));
       if libGSdll <> 0 then
       begin
         @gsapi_new_instance := GetProcAddress(libGSdll,'gsapi_new_instance');
         @gsapi_init_with_args := GetProcAddress(libGSdll,'gsapi_init_with_args');
         @gsapi_exit := GetProcAddress(libGSdll,'gsapi_exit');
         @gsapi_delete_instance := GetProcAddress(libGSdll,'gsapi_delete_instance');
         New(GSinstance);
         ErrorCode := gsapi_new_instance(@GSinstance,nil);
         if ErrorCode <> 0 then
           MsgOK('Impossible to open an instance of Ghostscript. Error code: ' + Int2Str(ErrorCode));
         try
           SetLength(Args,11);
           Args[0] := '-q';
           Args[1] := '-dNOPAUSE';
           Args[2] := '-dBATCH';
           Args[3] := '-dSAFER';
           Args[4] := '-sDEVICE=png16m';
           Args[5] := '-r300';
           Args[6] := '-dGraphicsAlphaBits=4';
           Args[7] := '-dFirstPage=1';
           Args[8] := '-dLastPage=1';
           Args[9] := PChar('-sOutputFile=' + ImageFileName);
           Args[10] := PChar(ExtractShortPathName(PDFFileName));
           ErrorCode := gsapi_init_with_args(GSinstance,Length(Args),Args);
           if ErrorCode <> 0 then
             MsgOK('Error printing document: ' + ImageFileName);
           gsapi_exit(GSinstance);
         finally
           gsapi_delete_instance(GSinstance);
         end;
         GSinstance := nil;
         FreeLibrary(libGSdll);
       end;
     end;
    end;

    procedure ButtonClick(Dummy: Pointer; Sender: PControl);
    var
     Counter: Integer;
    begin
     for Counter := 0 to FileList.Count -1 do
       ProcessPDF(FileList.Items[Counter],ChangeFileExt(FileList.Items[Counter],'.png') );
    end;

    begin
     Applet := NewForm(nil,'');
     FileList := NewEditbox(Applet,[eoMultiline,eoReadonly]);
     FileList.Color := clWhite;
     FileList.Add('c:\1.pdf' + #$0D#$0A);
     FileList.Add('c:\2.pdf' + #$0D#$0A);
     FileList.Add('c:\3.pdf' + #$0D#$0A);
     Button := NewButton(Applet,'Convert').PlaceRight;
     Button.OnClick := TOnEvent(MakeMethod(nil,@ButtonClick));
     Run(Applet);
    end.



    On first loop:

    MsgOK('Source = ' + PDFFileName + #$0D#$0A + 'Destination = ' + ImageFileName);



    Source = c:\1.pdf  Destination = c:\1.png

    Afterwards:

    Source =   Destination = .png

    All variables - including Counter - no longer contain valid data.

    Can anyone offer any advice. Thanks in advance.
  • Vladimir Kladov © (17.10.07 18:19) [1]
    OleInit? Don't know, I did not work with it.
  • Jon © (17.10.07 20:46) [2]
    Thank you but OleInit does not work.

    The above code works once, but not again.
    I assume that it is a memory management issue.
    Is there a better way to load a library?
  • Vladimir Kladov © (18.10.07 15:41) [3]
    If the DLL contains bugs, it is still possible to use it this way:
    - you run another instance of your app, passing some parameters to it via command line + memory mapped file,
    - there it run silently and hidden and terminates as usual. In this case all loaded DLL's are killed freeing all the allocated resources and w/o touching the main application any way.
  • Jon © (18.10.07 16:10) [4]
    Thank you very much for the suggestion- shall try it.
    What do you mean by "memory mapped file"?
  • Vladimir Kladov © (18.10.07 16:22) [5]
    If you don't know what is it, then you don't need it, just forget it :)
    (But in MSDN you can read all about it. Shortly: the fastest way to 1) handle giant files 2) to exchange large data between separate processes).
  • Jon © (18.10.07 16:43) [6]
    Understood - researching it now. Thank you :-)
 
Конференция "KOL" » Problem with LoadLibrary
Есть новые Нет новых   [134431   +10][b:0][p:0.003]