Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Problem with LoadLibrary


Jon ©   (2007-10-17 17:44:00) 

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.


Jon   (2007-10-18 16:43:00) [1]

Understood - researching it now. Thank you :-)


Vladimir Kladov   (2007-10-18 16:22:00) [2]

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   (2007-10-18 16:10:00) [3]

Thank you very much for the suggestion- shall try it.
What do you mean by "memory mapped file"?


Vladimir Kladov   (2007-10-18 15:41:00) [4]

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   (2007-10-17 20:46:00) [5]

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   (2007-10-17 18:19:00) [6]

OleInit? Don't know, I did not work with it.


Наверх

Титульная страница Поиск, карта сайта Написать письмо