Recent

Author Topic: Help me with create .dll and .so  (Read 21244 times)

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Help me with create .dll and .so
« on: June 24, 2010, 09:39:59 pm »
I created a C library which allows me to obtain lists of strings! Who will help me turn it into a .dll and .so

Thanks
 :)
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Help me with create .dll and .so
« Reply #1 on: June 24, 2010, 10:11:14 pm »
Question ansistring but is equal to the string of C?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: Help me with create .dll and .so
« Reply #2 on: June 24, 2010, 11:29:03 pm »
Question ansistring but is equal to the string of C?

Use PChar when talking to C.

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Help me with create .dll and .so
« Reply #3 on: June 24, 2010, 11:39:53 pm »
Another question I've put in my dll as a parameter of the function PtrMiaLista * MiaLista

How do I declare in Free Pascal? It 'a pointer to a list of structures!
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: Help me with create .dll and .so
« Reply #4 on: June 25, 2010, 12:04:31 am »
Have a look at the RTL sources, there are a lot of declarations, like

 TSize = record
     cx : Longint;
     cy : Longint;
  end;

  PSize = ^TSize;     

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Help me with create .dll and .so
« Reply #5 on: June 25, 2010, 01:27:55 am »
Suppose I have a dll in the same folder as the software, called miadll.dll and which contains the procedure MiaProcedura (PtrMiaLista MiaLista *);

Correctly filled with dev-cpp. As I recall from lazarus?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Help me with create .dll and .so
« Reply #6 on: June 25, 2010, 02:15:31 am »
Then the dll that I wrote with Devcpp function is declared as follows:

EXTERN_C __declspec(dllexport) VOID GetListaDSN (PtrListaODBC * MiaLista);

Instead PtrListaODBC is declared:

typedef struct ListaODBC
{
   char dsn[256];
    char desc[256];
   struct ListaODBC * next;
}PtrListaODBC;


In my example below I tried to interact with lazarus dll. No crashes when I run, but I do not return the result I expect! How do I change it?


unit Unit1;

{$mode objfpc}{$H+}
{$ifdef unix}
{$linklib myfunc}
{$endif}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

  type
   PtrListaODBC = record
     dsn : PChar;
     desc : PChar;
     next: integer;
  end;




var
  Form1: TForm1;

function GetListaDSN(MiaLista: PtrListaODBC): PChar; cdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};

implementation

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
   app: PtrListaODBC;
begin
     GetListaDSN(app);
     Edit1.Text:=app.dsn;
end;

initialization
  {$I unit1.lrs}

end.
       
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Help me with create .dll and .so
« Reply #7 on: June 25, 2010, 03:09:11 am »
I changed the source but now crashes when I try to exploit the variable valore with the DSN list!  :o :o

unit Unit1;

{$mode objfpc}{$H+}
{$ifdef unix}
{$linklib myfunc}
{$endif}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

  PtrListaODBC=^appoggio;
   Appoggio = record
     dsn : PChar;
     desc : PChar;
     next: PtrListaODBC;
  end;


var
  Form1: TForm1;

function GetListaDSN(MiaLista: PtrListaODBC): PChar; cdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};

implementation

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
   app: PtrListaODBC;
   i: integer;
   valore: PChar;
begin
     app:=new (PtrListaODBC);
     GetListaDSN(app);
     i:=0;
     while (app<>nil) do
     begin
          valore:=app^.dsn;
          app:=app^.next;
     end;
end;

initialization
  {$I unit1.lrs}

end.     
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: Help me with create .dll and .so
« Reply #8 on: June 25, 2010, 03:17:11 am »
In this case, it's not PChar.
h2pas translates:

ListaODBC = record
          dsn : array[0..255] of char;
          desc : array[0..255] of char;
          next : ^ListaODBC;
       end;
     PtrListaODBC = ListaODBC;

Use h2pas for header translation. Probaby it's stdcall instead of cdecl, I don't know.

captian jaster

  • Guest
Re: Help me with create .dll and .so
« Reply #9 on: June 25, 2010, 03:53:40 am »
You can make pascal and C work together?

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: Help me with create .dll and .so
« Reply #10 on: June 25, 2010, 03:56:34 am »
You can make pascal and C work together?

Yes, using DLLs. The whole Windows API is in C, so if this would not work, you would not be able to create a Form or sth. in Pascal.

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Help me with create .dll and .so
« Reply #11 on: June 25, 2010, 04:25:48 am »
DLL Source

#include <windows.h>
#include <stdio.h>
#include "MyODBCLib.h"

EXTERN_C __declspec(dllexport) INT CountDSN ();
EXTERN_C __declspec(dllexport) VOID GetDSNNum (INT num , CHAR * Dsn,CHAR * Desc);

BOOL WINAPI __declspec(dllexport) LibMain (HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
  if(Reason==DLL_PROCESS_ATTACH)
   {
     return   TRUE;
     }

  if(Reason==DLL_PROCESS_DETACH)
     {
     return   TRUE;
     }

  return   FALSE;
}


EXTERN_C __declspec(dllexport) INT CountDSN ()
{
    PtrListaODBC * MiaLista;
    int ret;
    MiaLista=RecuperaListaODBC();
    ret=QuantiDSN(MiaLista);
    CancellaListaODBC(MiaLista);
    return ret;
}

EXTERN_C __declspec(dllexport) VOID GetDSNNum (INT num , CHAR * Dsn,CHAR * Desc)
{   
    PtrListaODBC * MiaLista;
    PtrListaODBC * app;
    int ret, i;
   
    MiaLista=RecuperaListaODBC();   
   app=MiaLista;
   i=0;
   while(app)
   {
      //printf("%s - %s\n", app->dsn, app->desc);
      
      if (i==num)
      {
            Dsn=(char*)malloc(sizeof(char)*strlen(app->dsn));
            sprintf(Dsn,app->dsn);   
            Desc=(char*)malloc(sizeof(char)*strlen(app->desc));
            sprintf(Desc,app->desc);           
        }
      i++;
      app=app->next;
   }
    CancellaListaODBC(MiaLista);
}


So given this information, someone can explain why I can not get the data I want?
I changed no more scores for the entire list, but knowing how many dsn tell him to return the first list, the second etc..



Lazarus source

unit Unit1;

{$mode objfpc}{$H+}
{$ifdef unix}
{$linklib myfunc}
{$endif}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

  PtrListaODBC=^appoggio;
   Appoggio = record
   dsn : array[0..255] of char;
   desc : array[0..255] of char;
   next: PtrListaODBC;
  end;

var
  Form1: TForm1;

//function GetListaDSN(MiaLista: PtrListaODBC): PChar; cdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};
function CountDSN(): integer;stdcall; cdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};
procedure GetDSNNum (num: integer;Dsn: PChar ;Desc: PChar);stdcall; cdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};


implementation

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
   app: PtrListaODBC;
   i: integer;
   valore: string;
   MioDsn: Pchar;
   MiaDesc: PChar;
begin
 i:=CountDSN();
 MioDSN:='--';
 GetDSNNum(2,MioDSN,MiaDesc);
 Edit1.Text:=IntToStr(i) + '   ' + MioDSN ;
end;

initialization
  {$I unit1.lrs}

end.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: Help me with create .dll and .so
« Reply #12 on: June 25, 2010, 04:55:22 am »
Code: [Select]
function CountDSN(): integer;stdcall; cdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};

You define stdcall AND cdecl? Does this compile?
It's either or..

http://www.freepascal.org/docs-html/prog/progsu80.html

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Help me with create .dll and .so
« Reply #13 on: June 25, 2010, 04:58:57 am »
Code: [Select]
function CountDSN(): integer;stdcall; cdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};

You define stdcall AND cdecl? Does this compile?
It's either or..

http://www.freepascal.org/docs-html/prog/progsu80.html

Now modify

//function GetListaDSN(MiaLista: PtrListaODBC): PChar; cdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};
function CountDSN(): integer;cppdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};
procedure GetDSNNum (num: integer;Dsn: PChar ;Desc: PChar);cppdecl; external {$ifdef windows} 'ProgettoDLLODBC.dll'{$endif};

But the result not change!
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: Help me with create .dll and .so
« Reply #14 on: June 25, 2010, 05:10:24 am »
I think you should declare the Pchars as var.

Make this little test in Pascal only:

Code: [Select]
procedure Getp(p:PChar);
var s:String;
begin
  s:='test';
  p:=PChar(s);
end;

procedure GetpV(var p:PChar);
var s:String;
begin
  s:='test';
  p:=PChar(s);
end;


procedure TForm1.Button1Click(Sender:TObject);
var p:PChar;
begin
GetP(p);
ShowMessage(p); //Garbage
GetPV(p);
ShowMessage(p); //Works
end;

 

TinyPortal © 2005-2018