Recent

Author Topic: 7zip callback error  (Read 1900 times)

softchina

  • Newbie
  • Posts: 6
7zip callback error
« on: August 04, 2020, 06:18:50 am »
lazarus uses 7zip to compress file,there is an error in the file below:

procedure TForm1.zlibClick(Sender: TObject);
var
    Arch: I7zOutArchive;
    Counter: Integer;
    sZipFile: string;
begin
    if not DirectoryExists(edtPath.Text) then
    begin
      ShowMessage('please select a file');
      edtPath.SetFocus;
    end;

    Memo1.Lines.Add('start compressing');
    Arch := CreateOutArchive(CLSID_CFormat7z);
    Arch.SetProgressCallback(nil,ProgressCallback);  //error line
    Arch.AddFiles(edtPath.Text, '', '*.*', False);

    SetCompressionLevel(Arch, 5);
    SevenZipSetCompressionMethod(Arch, m7LZMA);//important
    sZipFile := 'd:\path.7z';
    Arch.SaveToFile(sZipFile);
    Memo1.Lines.Append('finish compression,the file is:' + sZipFile);
    //CalcZipScale(sZipFile, ProgressBar1.Max);
end;

the error line Arch.SetProgressCallback(nil,ProgressCallback) messeage is :
unit1.pas(201,34) Error: Wrong number of parameters specified for call to "ProgressCallback"

i change the line to  Arch.SetProgressCallback(nil,@ProgressCallback) ,this time the error is :
unit1.pas(201,51) Error: Incompatible type for arg no. 2: Got "<procedure variable type of function(Pointer;Boolean;Int64):LongInt of object;StdCall>", expected "<procedure variable type of function(Pointer;Boolean;Int64):LongInt;StdCall>"

i use this code in delphi 10,it runs ok,but in lazarus can't run,why?

please help me!
« Last Edit: August 04, 2020, 06:55:50 am by softchina »

TRon

  • Hero Member
  • *****
  • Posts: 2432
Re: 7zip callback error
« Reply #1 on: August 04, 2020, 06:47:08 am »
the error line Arch.SetProgressCallback(nil,ProgressCallback) messeage is :
unit1.pas(201,50) Error: Incompatible type for arg no. 2: Got "<procedure variable type of function(Pointer;Boolean;Int64):LongInt of object;StdCall>", expected "<procedure variable type of function(Pointer;Boolean;Int64):LongInt;StdCall>"
Your progresscallback seems currently a method of your form while it expects a plain function.

softchina

  • Newbie
  • Posts: 6
Re: 7zip callback error
« Reply #2 on: August 04, 2020, 06:58:24 am »
function ProgressCallback(Sender: Pointer; total: boolean; value: int64) : HRESULT; stdcall;
begin
  if total then
    Form1.ProgressBar1.Max := value
  else
    Form1.ProgressBar1.Position := value;
  Result := S_OK;
end;   

TRon

  • Hero Member
  • *****
  • Posts: 2432
Re: 7zip callback error
« Reply #3 on: August 04, 2020, 07:01:41 am »
It is not as if the compiler is making things up, so you definitely have a method somewhere that is named ProgressCallback and that is seen first by the compiler.

Please post a full example that generates this error for you.

TRon

  • Hero Member
  • *****
  • Posts: 2432
Re: 7zip callback error
« Reply #4 on: August 04, 2020, 07:13:43 am »
Oh, I do see I quoted the wrong error message  :-[

The "@" prefix is indeed required for Free Pascal (that is different from Delphi, unless you compile your project in Delphi mode or use a specific switch so that you do not have to use the "@" prefix).

However the "of object" in the error-message still indicates that you have a method named ProgressCallback.

Alternatively you could try to prefix the name of ProgressCallback with the name of your unit where this function is implemented/declared.

Edit:
For example:
Code: Pascal  [Select][+][-]
  1. Arch.SetProgressCallback(nil,@unit1.ProgressCallback)

However, it would be better to figure out where the ProgressCallback method comes from and fix that in case that's possible.
« Last Edit: August 04, 2020, 08:02:55 am by TRon »

softchina

  • Newbie
  • Posts: 6
Re: 7zip callback error
« Reply #5 on: August 04, 2020, 08:26:45 am »
Thank you for TRon!

I think you got the key point,but the error still exists, unit1.pas(52,41) Error: Identifier not found "ProgressCallback" .

i list the whole code below:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls,
  windows;

type

  { TForm1 }

  TForm1 = class(TForm)
    edtPath: TEdit;
    Memo1: TMemo;
    ProgressBar1: TProgressBar;
    zlib: TButton;
    procedure zlibClick(Sender: TObject);
  private

  public
     function ProgressCallback(Sender: Pointer; total: boolean; value: int64):HRESULT;stdcall;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

Uses sevenzip;

procedure TForm1.zlibClick(Sender: TObject);
var
    Arch: I7zOutArchive;
    Counter: Integer;
    sZipFile: string;
begin
    if not DirectoryExists(edtPath.Text) then
    begin
      ShowMessage('please select a file');
      edtPath.SetFocus;
    end;

    Memo1.Lines.Add('start compressing');
    Arch := CreateOutArchive(CLSID_CFormat7z);
    Arch.SetProgressCallback(nil,@Unit1.ProgressCallback); //error line
    Arch.AddFiles(edtPath.Text, '', '*.*', False);

    SetCompressionLevel(Arch, 5);
    SevenZipSetCompressionMethod(Arch, m7LZMA);
    sZipFile := 'd:\path.7z';
    Arch.SaveToFile(sZipFile);
    Memo1.Lines.Append('finish compression,the file is:' + sZipFile);
    //CalcZipScale(sZipFile, ProgressBar1.Max);
end;


function ProgressCallback(Sender: Pointer; total: boolean; value: int64) : HRESULT; stdcall;
begin
  if total then
    Form1.ProgressBar1.Max := value
  else
    Form1.ProgressBar1.Position := value;
  Result := S_OK;
end;

end.

TRon

  • Hero Member
  • *****
  • Posts: 2432
Re: 7zip callback error
« Reply #6 on: August 04, 2020, 08:35:38 am »
Code: Pascal  [Select][+][-]
  1.   public
  2.      function ProgressCallback(Sender: Pointer; total: boolean; value: int64):HRESULT;stdcall;
  3.   end;
  4.  
That is called a method, which belongs to your class TForm1  :)

Remove that entry and you should be good to go.

edit:
o, wait. You also need to place the function progresscallback above your zlibClick event procedure or make a forward declaration to your progresscallback function.
« Last Edit: August 04, 2020, 08:38:44 am by TRon »

TRon

  • Hero Member
  • *****
  • Posts: 2432
Re: 7zip callback error
« Reply #7 on: August 04, 2020, 08:57:13 am »
Because it seems you are fairly new to this, i'll show you.

Like this:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls,
  9.   windows;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     edtPath: TEdit;
  17.     Memo1: TMemo;
  18.     ProgressBar1: TProgressBar;
  19.     zlib: TButton;
  20.     procedure zlibClick(Sender: TObject);
  21.   private
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. Uses sevenzip;
  34.  
  35. function ProgressCallback(Sender: Pointer; total: boolean; value: int64) : HRESULT; stdcall;
  36. begin
  37.   if total then
  38.     Form1.ProgressBar1.Max := value
  39.   else
  40.     Form1.ProgressBar1.Position := value;
  41.   Result := S_OK;
  42. end;
  43.  
  44.  
  45. procedure TForm1.zlibClick(Sender: TObject);
  46. var
  47.     Arch: I7zOutArchive;
  48.     Counter: Integer;
  49.     sZipFile: string;
  50. begin
  51.     if not DirectoryExists(edtPath.Text) then
  52.     begin
  53.       ShowMessage('please select a file');
  54.       edtPath.SetFocus;
  55.     end;
  56.  
  57.     Memo1.Lines.Add('start compressing');
  58.     Arch := CreateOutArchive(CLSID_CFormat7z);
  59.     Arch.SetProgressCallback(nil,@ProgressCallback); //error line
  60.     Arch.AddFiles(edtPath.Text, '', '*.*', False);
  61.  
  62.     SetCompressionLevel(Arch, 5);
  63.     SevenZipSetCompressionMethod(Arch, m7LZMA);
  64.     sZipFile := 'd:\path.7z';
  65.     Arch.SaveToFile(sZipFile);
  66.     Memo1.Lines.Append('finish compression,the file is:' + sZipFile);
  67.     //CalcZipScale(sZipFile, ProgressBar1.Max);
  68. end;
  69.  
  70.  
  71. end.
  72.  

or this:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls,
  9.   windows;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     edtPath: TEdit;
  17.     Memo1: TMemo;
  18.     ProgressBar1: TProgressBar;
  19.     zlib: TButton;
  20.     procedure zlibClick(Sender: TObject);
  21.   private
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. Uses sevenzip;
  34.  
  35. function ProgressCallback(Sender: Pointer; total: boolean; value: int64) : HRESULT; stdcall; forward;
  36.  
  37. procedure TForm1.zlibClick(Sender: TObject);
  38. var
  39.     Arch: I7zOutArchive;
  40.     Counter: Integer;
  41.     sZipFile: string;
  42. begin
  43.     if not DirectoryExists(edtPath.Text) then
  44.     begin
  45.       ShowMessage('please select a file');
  46.       edtPath.SetFocus;
  47.     end;
  48.  
  49.     Memo1.Lines.Add('start compressing');
  50.     Arch := CreateOutArchive(CLSID_CFormat7z);
  51.     Arch.SetProgressCallback(nil,@ProgressCallback); //error line
  52.     Arch.AddFiles(edtPath.Text, '', '*.*', False);
  53.  
  54.     SetCompressionLevel(Arch, 5);
  55.     SevenZipSetCompressionMethod(Arch, m7LZMA);
  56.     sZipFile := 'd:\path.7z';
  57.     Arch.SaveToFile(sZipFile);
  58.     Memo1.Lines.Append('finish compression,the file is:' + sZipFile);
  59.     //CalcZipScale(sZipFile, ProgressBar1.Max);
  60. end;
  61.  
  62. function ProgressCallback(Sender: Pointer; total: boolean; value: int64) : HRESULT; stdcall;
  63. begin
  64.   if total then
  65.     Form1.ProgressBar1.Max := value
  66.   else
  67.     Form1.ProgressBar1.Position := value;
  68.   Result := S_OK;
  69. end;
  70.  
  71. end.
  72.  

Both should work for your situation.

softchina

  • Newbie
  • Posts: 6
Re: 7zip callback error
« Reply #8 on: August 04, 2020, 09:05:32 am »
thank you TRon again!

 

TinyPortal © 2005-2018