Recent

Author Topic: function in dynamic DLL  (Read 4642 times)

skaner1900

  • Jr. Member
  • **
  • Posts: 59
function in dynamic DLL
« on: February 18, 2013, 07:49:18 pm »
Hi
i wrote a simple DLL:

Code: [Select]
library project1;
{$mode objfpc}{$H+}
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  {$ENDIF}{$ENDIF}
{$IFDEF WINDOWS}{$R project1.rc}{$ENDIF}

function NumCheck(s:string):string;stdcall;
begin
result:='abc';
end;

exports NumCheck;

begin
end.
         

and i tried to load it in my application:

Code: [Select]
type
  TDynamic_NumCheck = function(s:string):string;stdcall;
.
.
.
  private
    { private declarations }
     hHndl: TlibHandle;
     DynNumCheck : TDynamic_NumCheck; 
.
.
.
procedure TForm1.cb1Change(Sender: TObject);
begin
  if fileexists('libs\'+cb1.text) then
  begin
    hHndl:= LoadLibrary('libs\'+cb1.text);
    if hHndl <> 0 then begin
      pointer(DynNumCheck):= GetProcedureAddress(hHndl,'NumCheck');
    end;
  end;
  if not assigned(DynNumCheck) then showmessage('Błąd biblioteki');
  pointer(DynNumCheck):= nil;
  if hHndl <> 0 then UnloadLibrary(hHndl);
  hHndl:= 0;
end;
.
.
.
procedure TForm1.Button2Click(Sender: TObject);
var
  i:integer;
begin
  for i:=1 to sg1.RowCount-1 do
    begin
    sg1.Cells[2,i]:=string(DynNumCheck(sg1.Cells[0,i]));
    end;
end; 

And when I run this function i see : "Project xxx.exe raised exception class 'External: SIGSEGV'." or "Acces violation."
What's wrong?
« Last Edit: February 18, 2013, 07:51:12 pm by skaner1900 »

Takeda

  • Full Member
  • ***
  • Posts: 157
Re: function in dynamic DLL
« Reply #1 on: February 18, 2013, 08:15:21 pm »
Do you have "export" your function inside your Library??  :P

NOTE :
1. In random cases, it would be better to set the result as "PChar" or "PWideChar" instead "String", coz in some test I was failed to get the result from DLL if it's set as String.
2. Please see : http://www.freepascal.org/docs-html/prog/progch12.html#x247-26200012

Regards,
takeda
« Last Edit: February 18, 2013, 08:19:38 pm by Takeda »
Call me Takeda coz that's my true name.
Pascal coding using Lazarus => "Be native in any where.."

ƪ(˘⌣˘)┐ ƪ(˘⌣˘)ʃ ┌(˘⌣˘)ʃ

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: function in dynamic DLL
« Reply #2 on: February 18, 2013, 08:22:00 pm »
string is a reference counted data type. having a function returning a string type from a dll will return an invalid pointer because the dll and the exe have different memory managers exiting the function the dll memory manager sees that the result is not used and frees the memory the exe tries to access a freed memory and you get a GPF. In short you have violated rule #1 of dll creating, Never use a reference counted data type and do not rely on the dll's memory manager to allocate memory for your application.

Take a closer look on the windows API for example they use PChars and they require for you to inform the dll if the pchar passed has the required memory to hold the result if not it returns the amount of memory the result requires so your exe can allocate the memory for it.

You see where this is going I hope.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: function in dynamic DLL
« Reply #3 on: February 18, 2013, 10:15:58 pm »
Is that something that FPC could be made to warn about in compiler messages?

skaner1900

  • Jr. Member
  • **
  • Posts: 59
Re: function in dynamic DLL
« Reply #4 on: February 19, 2013, 03:36:19 am »
but i've got the same problem when i using pchar, or integer...

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: function in dynamic DLL
« Reply #5 on: February 19, 2013, 05:22:51 am »
Are you sure you must UnloadLibrary() right after it's loaded? I can't find any example that would do that.

Takeda

  • Full Member
  • ***
  • Posts: 157
Re: function in dynamic DLL
« Reply #6 on: February 19, 2013, 05:32:48 am »
Do you have "export" your function inside your Library??

Something like :
Code: [Select]
library TestLibrary;
 
 uses SysUtils, Classes;
 
function  MixedStr(AStr:PChar):PChar; stdcall; export;
var
 ATemp:String;
begin
ATemp:=AStr;
ATemp2:=ATemp+' . Now, you get it from DLL';

Result:= PChar(ATemp2);
   
end;
 
exports
 MixedStr;
 
begin
end.
 


Then you call it something like (Inside your EXE. It's Static Loaded, not the Dynamic one):

Code: [Select]
.....
var
    Form1: TForm1;
 
   function  MixedStr(AStr:PChar):PChar; stdcall; external 'TestLibrary.dll'
 
 implementation
 
 {$R *.lfm}
 
procedure TForm1.Button1Click(Sender: TObject) ;
var
 ATempStr, ATempStr2:String;
begin
    ATempStr2:=MixedStr(PChar(ATempStr));
    Caption:=ATempStr2;
end;
....
« Last Edit: February 19, 2013, 05:34:36 am by Takeda »
Call me Takeda coz that's my true name.
Pascal coding using Lazarus => "Be native in any where.."

ƪ(˘⌣˘)┐ ƪ(˘⌣˘)ʃ ┌(˘⌣˘)ʃ

 

TinyPortal © 2005-2018