Recent

Author Topic: FreeLibrary hangs program  (Read 6916 times)

guest48704

  • Guest
FreeLibrary hangs program
« on: July 26, 2018, 05:51:29 pm »
  When I execute the 'FreeLibrary(Dll1Handle)' below, the program returns the data from the dll correctly, but after clicking the ok button on the 'ShowMessage(DLL1Func(''))', the program hangs and will not close without doing a CTL-ALT-DEL operation.  Anyone know if anything is being done wrong here?  Will the dll unload itself automatically at program end?  Thanks.

W7 64

//Dll
library mixhashpw;

uses
    Windows, Classes, Sysutils, dialogs, Dynlibs;

function mixString(datain : string): string; stdcall;
var StgSort : TStringList; data : string;
begin
     StgSort := TStringList.Create;
     StgSort.Clear;
     StgSort.Sorted := True;
     StgSort.Add('3');
     StgSort.Add('5');
     StgSort.Add('1');
     StgSort.Add('4');
     StgSort.Add('2');
     data := StgSort.Text;
     StgSort.Free;

     Result := data;
end;

exports
       mixString;

begin

end.

-------------------------------------------

//Calling program
procedure TForm1.Button1Click(Sender: TObject);
var Dll1Handle: TLibHandle;
    DLL1Func: TDLL1Funct;
begin
     Dll1Handle := SafeLoadLibrary('mixhashpw.dll');

     if Dll1Handle > 0 then begin
        try
        DLL1Func := TDLL1Funct(GetProcedureAddress(Dll1Handle,'mixString'));

        if Assigned(DLL1Func) then begin
           ShowMessage(DLL1Func(''));                  //no pass something
           end
           else
           ShowMessage('Can''t load mixhashpw.dll');

        finally
        FreeLibrary(Dll1Handle);
        end;
     end;
end;

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: FreeLibrary hangs program
« Reply #1 on: July 26, 2018, 06:11:41 pm »
Don't use String type when passing data between main program and DLL. Use PChar instead.

Code: Pascal  [Select][+][-]
  1. ShowMessage(DLL1Func(''));

After executing this line, reference count to returned String will be zero and main program tries to free its allocated memory block. Because the memory block was allocated inside the DLL, main program will freeze or show other unexpected behaviour.

String type is managed type (reference counted. When its reference count reaches zero, memory allocted to String data will be freed) and both EXE and DLL have their own memory manager for it installed. So when DLL gets unloaded, all memory what was allocated during inside its execution will be freed. This includes Strings.
« Last Edit: July 26, 2018, 06:17:41 pm by Cyrax »

guest48704

  • Guest
Re: FreeLibrary hangs program
« Reply #2 on: July 26, 2018, 08:44:16 pm »
Thanks.  Didn't know that. That was definiely the problem.  Here is the entire fix:

Dll:
library mixhashpw;

uses
    Windows, Classes, Sysutils, dialogs; //, Dynlibs;

function mixString(datain : string): PChar; stdcall;
var StgSort : TStringList; data : string;
begin
     StgSort := TStringList.Create;
     StgSort.Clear;
     StgSort.Sorted := True;
     StgSort.Add('3');
     StgSort.Add('5');
     StgSort.Add('1');
     StgSort.Add('4');
     StgSort.Add('2');
     data := StgSort.Text;
     StgSort.Free;

     Result := PChar(data);
end;

exports
       mixString;
begin
end.

-------------------------------------------

//Program:
unit Unit1;

{$mode Delphi}

interface

uses
    Windows, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;  //, Dynlibs;

type

{ TForm1 }

TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;

    procedure Button1Click(Sender: TObject);
    private
    { private declarations }
    public
    { public declarations }
end;

var
Form1: TForm1;

implementation

type
  TDLL1Funct = function(str : string): PChar; stdcall;   //pass sonething

{$R *.lfm}

{ TForm1 }

//Retrieve from dll
procedure TForm1.Button1Click(Sender: TObject);
var Dll1Handle: TLibHandle;
    DLL1Func: TDLL1Funct;
begin
     Dll1Handle := SafeLoadLibrary('mixhashpw.dll');

     if Dll1Handle > 0 then begin
        try
        DLL1Func := TDLL1Funct(GetProcedureAddress(Dll1Handle,'mixString'));

        if Assigned(DLL1Func) then begin
           Memo1.Text := DLL1Func('');
////           ShowMessage(DLL1Func(''));
           end
           else
           ShowMessage('Can''t load mixhashpw.dll');

        finally
        FreeLibrary(Dll1Handle);
        end;
     end;
end;

end.


Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: FreeLibrary hangs program
« Reply #3 on: July 26, 2018, 08:48:15 pm »
Thanks.  Didn't know that. That was definiely the problem.  Here is the entire fix:

That's still not safe.

In general, use a buffer to pass back strings from a dynamic library. You're passing back a pointer to a local variable in the library's function.

See how ndfd.pas (in p4g.zip) does it in Part 2 of Pascal Dynamic Libraries series:

https://macpgmr.github.io

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: FreeLibrary hangs program
« Reply #4 on: July 26, 2018, 09:07:43 pm »
library mixhashpw;

If I understood the name properly, don't use a dll to do that, or at least encrypt the parameters and use less obvious names.

guest48704

  • Guest
Re: FreeLibrary hangs program
« Reply #5 on: July 28, 2018, 11:33:04 pm »
Thanks for the heads up. 

I will look at Pascal Dynamic Libraries.

The encryption sounding dll is not really encrypting anything.

guest48704

  • Guest
Re: FreeLibrary hangs program
« Reply #6 on: July 30, 2018, 07:34:02 pm »
Thanks.  Didn't know that. That was definiely the problem.  Here is the entire fix:

That's still not safe.

In general, use a buffer to pass back strings from a dynamic library. You're passing back a pointer to a local variable in the library's function.

See how ndfd.pas (in p4g.zip) does it in Part 2 of Pascal Dynamic Libraries series:

https://macpgmr.github.io

  Wonder what is not safe about Cyrax explanation.

 

TinyPortal © 2005-2018