Lazarus

Programming => General => Topic started by: hidenming on May 15, 2018, 08:13:28 pm

Title: Importing function from dll
Post by: hidenming on May 15, 2018, 08:13:28 pm
Hello guys.
I came from Delphi and am starting to use this wonderful tool called Lazarus, but I'm having some problems importing functions from a dll.
I do exactly as in Delphi but the compiler accuses error in Lazarus
Here is the code:
Code: Pascal  [Select][+][-]
  1. type
  2.   TGetClassName = function: String; stdcall;
  3. var
  4.   lName: String;
  5.   lClassName: TGetClassName;
  6.   lHandle: TLibHandle;
  7. begin
  8.   lHandle := dynlibs.LoadLibrary('project1.dll');
  9.   if lHandle = dynlibs.NilHandle then Exit;
  10.   lClassName := TGetClassName(dynlibs.GetProcedureAddress(lHandle, 'GetClassName'));
  11.   lName := lClassName; //compiling error goes here
  12. end;  
  13.  
Here is the error:
unit1.pas(48,12) Error: Incompatible types: got "<procedure variable type of function:AnsiString;StdCall>" expected "AnsiString"

Can someone please help me?
Title: Re: Importing function from dll
Post by: jamie on May 16, 2018, 02:19:28 am
What is TGetClassName ?

with the way it is being used, it should be a Pointer to something?

 and if that being the case then you need to use the ^
so I assume it should be returning a string type?

Title: Re: Importing function from dll
Post by: ASerge on May 16, 2018, 03:43:36 am
Code: Pascal  [Select][+][-]
  1. type
  2.   TGetClassName = function: String; stdcall;
  3. var
  4.   lName: String;
  5.   lClassName: TGetClassName;
  6.   lHandle: TLibHandle;
  7. begin
  8.   lHandle := dynlibs.LoadLibrary('project1.dll');
  9.   if lHandle = dynlibs.NilHandle then Exit;
  10.   lClassName := TGetClassName(dynlibs.GetProcedureAddress(lHandle, 'GetClassName'));
  11.   lName := lClassName; //compiling error goes here
  12. end;  
  13.  
lName := lClassName(); // parenthesis!
Title: Re: Importing function from dll
Post by: ASerge on May 16, 2018, 03:46:44 am
But using string as the result of a function is a bad idea. A string is a managed type, and you will have both a program and a library to manage it. There may be conflicts (no memory release or double release).
Title: Re: Importing function from dll
Post by: marcov on May 16, 2018, 12:40:24 pm
I do exactly as in Delphi but the compiler accuses error in Lazarus

1. Do you compile this in mode delphi?
2. dynlibs is not a delphi unit so YMMV with details.

And Aserge has a point. Managed types over DLL<->EXE borders is not a good idea.
Title: Re: Importing function from dll
Post by: CCRDude on May 16, 2018, 03:58:35 pm
Depending on the $MODE, you need to include brackets to assign the call result, not the function:
Quote
lName := lClassName();
Title: Re: Importing function from dll
Post by: mangakissa on May 17, 2018, 08:36:03 am
When send a string back from a library, use pchar().
But that was years ago with delphi. But I don't know how dynlibs works.
Title: Re: Importing function from dll
Post by: Thaddy on May 17, 2018, 09:00:32 am
Indeed. Although in principle and only fpc.dll to fpc execuatable (or delphi dll and delphi executable) can work both ways with strings if a shared memory manager is installed.(e.g. sharemem.dll for Delphi)
But generally do not use Pascal strings, with shared libraries use PChar string types. That will also work with other languages.

The exception is COM dll's and their type libraries, together with the use of BWSTR/WideString types: these will work since those are not reference counted by FPC but by a COM marshaller but that depends on platform (usually windows only)
TinyPortal © 2005-2018