Recent

Author Topic: Convert C to Lazarus  (Read 13233 times)

danny

  • New Member
  • *
  • Posts: 29
Convert C to Lazarus
« on: March 21, 2013, 09:28:08 pm »
I have an application that uses functions from a file mylib.so. How to use it in Lazarus?

In compiling gcc as:

gcc -g myapp.c -I ./mylib.so

How to use the functions that are within the mylib.so ?  (as was used in gcc with-I parameter).

Thanks for the help.

Fred vS

  • Hero Member
  • *****
  • Posts: 3829
    • StrumPract is the musicians best friend
Re: Convert C to Lazarus
« Reply #1 on: March 21, 2013, 09:49:30 pm »
Hello.

First you need the mylib.h file (C header) of mylib.so.
This file enumerate the functions used in mylib.so.

Then, translate that mylib.h into pascal (mylib.pas).

Add in the use section : mylib.pas.

Play with your mylib.so functions in the application.
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

danny

  • New Member
  • *
  • Posts: 29
Re: Convert C to Lazarus
« Reply #2 on: March 21, 2013, 09:59:23 pm »
Ok, I translated that mylib.h into pascal, how i use file mylib.so ?

I copied to the /usr/lib with the name libmylib.so compiled and returned "project1.lpr (20.1) Error: Error while linking"

Sorry my english, I'm brazilian nerd.

Fred vS

  • Hero Member
  • *****
  • Posts: 3829
    • StrumPract is the musicians best friend
Re: Convert C to Lazarus
« Reply #3 on: March 21, 2013, 10:26:31 pm »
Quote
I copied to the /usr/lib with the name libmylib.so compiled and returned "project1.lpr (20.1) Error: Error while linking"

That must be something else in your code because,when you compile, the libmylib.pas do not load the library.

The library is loaded when you run the program.

Could you give some part of your code ( use section and mylib.pas ) ?

EDIT : Add mylib.pas in use section of form1.pas not in project.dpr
« Last Edit: March 21, 2013, 10:33:07 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

danny

  • New Member
  • *
  • Posts: 29
Re: Convert C to Lazarus
« Reply #4 on: March 21, 2013, 10:43:55 pm »
How to get the function declaration in mylib.pas?

C header:
int Funcion1(void);

Lazarus:
function Function1:integer; cdecl; external;

As Lazarus will know that Function1 is Mylib.so?

Fred vS

  • Hero Member
  • *****
  • Posts: 3829
    • StrumPract is the musicians best friend
Re: Convert C to Lazarus
« Reply #5 on: March 21, 2013, 10:56:30 pm »
Quote
rus will know that Function1 is Mylib.so?

If you use static libraries, in your Mylib.pas it must be declared :
Code: [Select]
const
{$IFDEF MSWINDOWS}
  Mylib = 'Mylib.dll';
{$ELSE}
      Mylib = 'Mylib.so';
       {$ENDIF}
 


and inside code for example :

Code: [Select]
function Function1:integer; cdecl; external Mylib name 'Function1';
But you can also use dynamic loading (much better) and choose your location of library at run-time... ;)
« Last Edit: March 21, 2013, 10:59:36 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

danny

  • New Member
  • *
  • Posts: 29
Re: Convert C to Lazarus
« Reply #6 on: March 21, 2013, 11:26:00 pm »
Thanks, it worked.

Now, how is the dynamic loading that you say?
I can choose the place of the library?

Fred vS

  • Hero Member
  • *****
  • Posts: 3829
    • StrumPract is the musicians best friend
Re: Convert C to Lazarus
« Reply #7 on: March 21, 2013, 11:56:24 pm »
Quote
Now, how is the dynamic loading that you say?

Opa, amigo, isto é a cosa legal do Lazarus-Pascal : Dynamic loading of libraries ...

Dynamic loading of libraries, the must of Lazarus-Pascal...
For that you need to add in use section of mylib.pas :
Code: [Select]
uses
  dynlibs

Then add the dynamic load function :
Code: [Select]
Function Load_mylib(const dllfilename:string) :boolean;

Then create the Vars that will hold our dynamically loaded functions :
Code: [Select]
var Function1:integer; {$IFDEF windows}stdcall{$ELSE}cdecl{$ENDIF};

and the var that will hold our handle for the dll.
Code: [Select]
var lib_Handle:TLibHandle;
Then in implementation section :
Code: [Select]
implementation

Function Load_mylib (const dllfilename:string) :boolean;
begin
  Result := False;
  if lib_Handle<>0 then result:=true {is it already there ?}
  else begin {go & load the library}
    if Length(dllfilename) = 0 then exit;
    lib_Handle:=DynLibs.LoadLibrary(dllfilename); // obtain the handle we want

if lib_Handle <> DynLibs.NilHandle then
       begin {now we tie the functions to the VARs from above}

Pointer(Function1) := DynLibs.GetProcedureAddress(lib_Handle,PChar('Function1'));

/// all the other functions...

end;

Do not forget to unload the library with :

Code: [Select]
Procedure Unload_mylib;
begin
  if lib_Handle<>DynLibs.NilHandle then
     begin
         DynLibs.UnloadLibrary(lib_Handle);
     end;
  lib_Handle:=DynLibs.NilHandle;
end;

In main form1.pas, you can add at formcreate or also in a buttonclick procedure :

Code: [Select]
Load_mylib('myfolder/mylib.so')
So you can load the library when, from where you want and use your mylib functions the same way than for static library.
 ;D
« Last Edit: March 22, 2013, 12:13:42 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Deepaak

  • Sr. Member
  • ****
  • Posts: 454
Re: Convert C to Lazarus
« Reply #8 on: March 22, 2013, 04:56:41 am »
A small bit of correction in code.

Static libraries get their code compiled into the executable. This means that your executable is bigger, but you do not need the library during runtime. Dynamic libraries do not get compiled into the executable, instead they are loaded during runtime. This means the dynamic library must exist on the system you are running the executable on.

So

Code: [Select]
const
{$IFDEF MSWINDOWS}
  Mylib = 'Mylib.dll';
{$ELSE}
      Mylib = 'Mylib.so';
       {$ENDIF}
 


this is dynamic not static. Because it depends on an external .dll/.so file.
If it is depended in .a(static file) then it is static.

Code: [Select]
uses
  dynlibs

is used when you load your dll when it is required and unloaded after completing your task (dynamic loading).
It saves memory and make program faster.


For Static Libraries, you must use
Code: [Select]
unit demo
{$mode objfpc}
{$LinkLib 'yourlib.a'}

function Function1:integer; cdecl; external;
Implementation

End.

This is true static. Here you don't have to distribute the yourlib.a file with your executable, unlike .dll/.so file.
Holiday season is online now. :-)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Convert C to Lazarus
« Reply #9 on: March 22, 2013, 10:10:51 am »
Quote
this is dynamic not static
I think it needs to be made clear whether we're talking about dynamic library or dynamic loading (of dynamic library)...

TurboRascal

  • Hero Member
  • *****
  • Posts: 672
  • "Good sysadmin. Bad programmer."™
Re: Convert C to Lazarus
« Reply #10 on: March 22, 2013, 11:44:41 am »
People often confuse "static libraries" and "static loading of dynamic libraries"...
Regards, ArNy the Turbo Rascal
-
"The secret is to give them what they need, not what they want." - Scotty, STTNG:Relics

Fred vS

  • Hero Member
  • *****
  • Posts: 3829
    • StrumPract is the musicians best friend
Re: Convert C to Lazarus
« Reply #11 on: March 22, 2013, 02:25:22 pm »
Quote
I think it needs to be made clear whether we're talking about dynamic library or dynamic loading (of dynamic library)...

I agree...

@ deepaak99 : That is a good beginning of explanation. 

Maybe a example how to deal with different option :
- 1. example with static lib included in exe.
- 2. example with dynamic lib in /usr/lib loaded at init of program ( how do you call that ?)
- 3. example with dynamic lib, dynamically loaded, in the folder you want ( i think you call that dynamic loading of libraries).

And finally a benchmark measuring the result of the 3 ways of loading the same library.

 
« Last Edit: March 22, 2013, 02:28:24 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Deepaak

  • Sr. Member
  • ****
  • Posts: 454
Re: Convert C to Lazarus
« Reply #12 on: March 22, 2013, 04:30:25 pm »
Code: [Select]
const
{$IFDEF MSWINDOWS}
    Mylib = 'Mylib.dll' ;
{$ELSE}
    Mylib = 'Mylib.so' ;
{$ENDIF}

It is static Loading of DLL/SO File.

Code: [Select]
uses
    dynlibs

It is used in dynamic dll loading..

More Info.

http://delphi.about.com/od/windowsshellapi/a/delphi-dll-loading-static-dynamic.htm

Holiday season is online now. :-)

Deepaak

  • Sr. Member
  • ****
  • Posts: 454
Re: Convert C to Lazarus
« Reply #13 on: March 22, 2013, 05:19:08 pm »

@ deepaak99 : That is a good beginning of explanation. 

Maybe a example how to deal with different option :
- 1. example with static lib included in exe.
- 2. example with dynamic lib in /usr/lib loaded at init of program ( how do you call that ?)
- 3. example with dynamic lib, dynamically loaded, in the folder you want ( i think you call that dynamic loading of libraries).

And finally a benchmark measuring the result of the 3 ways of loading the same library.


As far as my knowledge it is as follows.

1. example with static lib included in exe.

Code: [Select]
unit demo
{$mode objfpc}
{$LinkLib 'yourlib.a'}

function Function1:integer; cdecl; external;
Implementation

End.

2. example with dynamic lib in /usr/lib loaded at init of program ( how do you call that ?)

Static Linking of Dynamic Library (.dll/.so).

Code: [Select]
const
{$IFDEF MSWINDOWS}
    Mylib = 'Mylib.dll' ;
{$ELSE}
    Mylib = 'Mylib.so' ;
{$ENDIF}

function Function1:integer; cdecl; external Mylib name 'Function1';


- 3. example with dynamic lib, dynamically loaded, in the folder you want ( i think you call that dynamic loading of libraries).
Quote
As you had described using dynlibs



@ deepaak99 : That is a good beginning of explanation. 

Thank you, it had cleared some of my doubts tooo.
« Last Edit: March 22, 2013, 05:34:11 pm by deepaak99 »
Holiday season is online now. :-)

Fred vS

  • Hero Member
  • *****
  • Posts: 3829
    • StrumPract is the musicians best friend
Re: Convert C to Lazarus
« Reply #14 on: March 22, 2013, 09:49:40 pm »
@ deepaak99 : many thanks, much clearer for me as wellll.  ;)

So, in resume,  we have 3 ways to load libraries.

1- Static loading of built-in Library. (example 1)
2- Static Linking of Dynamic Library. (example 2)
3- Dynamic Linking of Dynamic Library. (example 3)

Do you agree with those appellations ?

Cfr benchmark, is there a plus to use Static Linking of Dynamic Library vs Dynamic Linking of Dynamic Library ?
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

 

TinyPortal © 2005-2018