View Issue Details

IDProjectCategoryView StatusLast Update
0034387FPCRTLpublic2019-12-14 15:45
ReportersilvioprogAssigned ToMarco van de Voort 
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionunable to reproduce 
Product Version3.3.1Product Build 
Target VersionFixed in Version 
Summary0034387: [PATCH] allows to build FFI units on Win32
DescriptionHi.

The attached patch allows to build the FFI units on Win32 and adds a new example calling an object method from it.

Thank you!
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget-
Attached Files
  • 0001-allows-to-build-ffi-units-on-win32-adds-a-new-exampl.patch.sig (310 bytes)
  • 0001-allows-to-build-ffi-units-on-win32-adds-a-new-exampl.patch (5,221 bytes)
    From b07ca853c73e6ac6351e1ae89110e4332f6cf778 Mon Sep 17 00:00:00 2001
    From: silvioprog <silvioprog@gmail.com>
    Date: Thu, 4 Oct 2018 17:26:30 -0300
    Subject: [PATCH 1/1] allows to build ffi units on win32; adds a new example
     calling an object method. (patch by silvioprog)
    
    ---
     packages/libffi/examples/simpleobj.pp | 56 +++++++++++++++++++++++++++
     packages/libffi/fpmake.pp             |  5 ++-
     packages/libffi/src/ffi.pp            | 42 ++++++++++++--------
     3 files changed, 84 insertions(+), 19 deletions(-)
     create mode 100644 packages/libffi/examples/simpleobj.pp
    
    diff --git a/packages/libffi/examples/simpleobj.pp b/packages/libffi/examples/simpleobj.pp
    new file mode 100644
    index 0000000000..98f420f1f0
    --- /dev/null
    +++ b/packages/libffi/examples/simpleobj.pp
    @@ -0,0 +1,56 @@
    +program simpleobj;
    +
    +{$IFDEF FPC}
    + {$MODE DELPHI}
    +{$ENDIF}
    +{$IFDEF MSWINDOWS}
    + {$APPTYPE CONSOLE}
    +{$ENDIF}
    +
    +uses
    +  Classes,
    +  FFI;
    +
    +type
    +  TMath = class(TPersistent)
    +  published
    +    function Sum(A, B: Integer): Integer;
    +  end;
    +
    +function TMath.Sum(A, B: Integer): Integer;
    +begin
    +  Result := A + B;
    +end;
    +
    +var
    +  m: TMath;
    +  cif: ffi_cif;
    +  args: array[0..2] of pffi_type;
    +  vals: array[0..2] of pointer;
    +  rc: ffi_arg;
    +  a, b: Integer;
    +begin
    +  m := TMath.Create;
    +  try
    +    args[0] := @ffi_type_pointer;
    +    args[1] := @ffi_type_sint;
    +    args[2] := @ffi_type_sint;
    +    if ffi_prep_cif(@cif, FFI_REGISTER, 3, @ffi_type_sint, @args[0]) <> FFI_OK then
    +    begin
    +      WriteLn('ffi_prep_cif failed');
    +      Halt(1);
    +    end;
    +    a := 2;
    +    b := 3;
    +    vals[0] := m;
    +    vals[1] := @a;
    +    vals[2] := @b;
    +    ffi_call(@cif, ffi_fn(m.MethodAddress('sum')), @rc, @vals[0]);
    +    WriteLn('Sum: ', rc);
    +{$IFDEF MSWINDOWS}
    +    ReadLn;
    +{$ENDIF}
    +  finally
    +    m.Free;
    +  end;
    +end.
    \ No newline at end of file
    diff --git a/packages/libffi/fpmake.pp b/packages/libffi/fpmake.pp
    index 1d47947e1e..8e189e12b9 100644
    --- a/packages/libffi/fpmake.pp
    +++ b/packages/libffi/fpmake.pp
    @@ -23,8 +23,8 @@ begin
         P.Email := 'libffi-discuss@sourceware.org';
         P.Description := 'Headers for the libFFI library (Foreign Function Interface)';
         P.NeedLibC:= true;  // true for headers that indirectly link to libc?
    -    P.OSes := [linux];
    -    P.CPUs := [x86_64];
    +    P.OSes := [linux,win32,win64];
    +    P.CPUs := [i386,x86_64];
         P.Dependencies.Add('rtl-objpas');
     
         P.SourcePath.Add('src');
    @@ -36,6 +36,7 @@ begin
     
         P.ExamplePath.Add('examples');
         P.Targets.AddExampleProgram('simple.pp');
    +    P.Targets.AddExampleProgram('simpleobj.pp');
     
     {$ifndef ALLPACKAGES}
         Run;
    diff --git a/packages/libffi/src/ffi.pp b/packages/libffi/src/ffi.pp
    index 208a3a4365..b2b59d98f7 100644
    --- a/packages/libffi/src/ffi.pp
    +++ b/packages/libffi/src/ffi.pp
    @@ -267,7 +267,7 @@ const
     }
     
     const
    -  ffilibrary = 'ffi';
    +  ffilibrary = {$ifdef mswindows}'libffi-6'{$else}'ffi'{$endif};
     
     {$if defined(CPUX86) and not defined(WIN64)}
       { Note: we can not use FPC_HAS_TYPE_EXTENDED here as libffi won't have the
    @@ -285,30 +285,38 @@ type
         elements: ppffi_type;
       end;
     
    +{$push}{$macro on}
    + {$ifdef CPU64}
    +  {$define extcvar:=cvar external}
    + {$else}
    +  {$define extcvar:=external}
    + {$endif}
    +{$pop}
    +
     var
    -  ffi_type_void: ffi_type; cvar; external ffilibrary;
    -  ffi_type_uint8: ffi_type; cvar; external ffilibrary;
    -  ffi_type_sint8: ffi_type; cvar; external ffilibrary;
    -  ffi_type_uint16: ffi_type; cvar; external ffilibrary;
    -  ffi_type_sint16: ffi_type; cvar; external ffilibrary;
    -  ffi_type_uint32: ffi_type; cvar; external ffilibrary;
    -  ffi_type_sint32: ffi_type; cvar; external ffilibrary;
    -  ffi_type_uint64: ffi_type; cvar; external ffilibrary;
    -  ffi_type_sint64: ffi_type; cvar; external ffilibrary;
    -  ffi_type_float: ffi_type; cvar; external ffilibrary;
    -  ffi_type_double: ffi_type; cvar; external ffilibrary;
    -  ffi_type_pointer: ffi_type; cvar; external ffilibrary;
    +  ffi_type_void: ffi_type; extcvar ffilibrary;
    +  ffi_type_uint8: ffi_type; extcvar ffilibrary;
    +  ffi_type_sint8: ffi_type; extcvar ffilibrary;
    +  ffi_type_uint16: ffi_type; extcvar ffilibrary;
    +  ffi_type_sint16: ffi_type; extcvar ffilibrary;
    +  ffi_type_uint32: ffi_type; extcvar ffilibrary;
    +  ffi_type_sint32: ffi_type; extcvar ffilibrary;
    +  ffi_type_uint64: ffi_type; extcvar ffilibrary;
    +  ffi_type_sint64: ffi_type; extcvar ffilibrary;
    +  ffi_type_float: ffi_type; extcvar ffilibrary;
    +  ffi_type_double: ffi_type; extcvar ffilibrary;
    +  ffi_type_pointer: ffi_type; extcvar ffilibrary;
     {$ifdef HAVE_LONG_DOUBLE}
    -  ffi_type_longdouble: ffi_type; cvar; external ffilibrary;
    +  ffi_type_longdouble: ffi_type; extcvar ffilibrary;
     {$else}
       ffi_type_longdouble: ffi_type absolute ffi_type_double;
     {$endif}
     
     {$if FFI_TARGET_HAS_COMPLEX_TYPE}
    -  ffi_type_complex_single: ffi_type; cvar; external ffilibrary;
    -  ffi_type_complex_double: ffi_type; cvar; external ffilibrary;
    +  ffi_type_complex_single: ffi_type; extcvar ffilibrary;
    +  ffi_type_complex_double: ffi_type; extcvar ffilibrary;
       {$ifdef HAVE_LONG_DOUBLE}
    -  ffi_type_complex_longdouble: ffi_type; cvar; external ffilibrary;
    +  ffi_type_complex_longdouble: ffi_type; extcvar ffilibrary;
       {$endif}
     {$endif}
     
    -- 
    2.17.1
    
    

Activities

silvioprog

2018-10-04 22:33

reporter  

0001-allows-to-build-ffi-units-on-win32-adds-a-new-exampl.patch.sig (310 bytes)

silvioprog

2018-10-04 22:34

reporter  

0001-allows-to-build-ffi-units-on-win32-adds-a-new-exampl.patch (5,221 bytes)
From b07ca853c73e6ac6351e1ae89110e4332f6cf778 Mon Sep 17 00:00:00 2001
From: silvioprog <silvioprog@gmail.com>
Date: Thu, 4 Oct 2018 17:26:30 -0300
Subject: [PATCH 1/1] allows to build ffi units on win32; adds a new example
 calling an object method. (patch by silvioprog)

---
 packages/libffi/examples/simpleobj.pp | 56 +++++++++++++++++++++++++++
 packages/libffi/fpmake.pp             |  5 ++-
 packages/libffi/src/ffi.pp            | 42 ++++++++++++--------
 3 files changed, 84 insertions(+), 19 deletions(-)
 create mode 100644 packages/libffi/examples/simpleobj.pp

diff --git a/packages/libffi/examples/simpleobj.pp b/packages/libffi/examples/simpleobj.pp
new file mode 100644
index 0000000000..98f420f1f0
--- /dev/null
+++ b/packages/libffi/examples/simpleobj.pp
@@ -0,0 +1,56 @@
+program simpleobj;
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+{$IFDEF MSWINDOWS}
+ {$APPTYPE CONSOLE}
+{$ENDIF}
+
+uses
+  Classes,
+  FFI;
+
+type
+  TMath = class(TPersistent)
+  published
+    function Sum(A, B: Integer): Integer;
+  end;
+
+function TMath.Sum(A, B: Integer): Integer;
+begin
+  Result := A + B;
+end;
+
+var
+  m: TMath;
+  cif: ffi_cif;
+  args: array[0..2] of pffi_type;
+  vals: array[0..2] of pointer;
+  rc: ffi_arg;
+  a, b: Integer;
+begin
+  m := TMath.Create;
+  try
+    args[0] := @ffi_type_pointer;
+    args[1] := @ffi_type_sint;
+    args[2] := @ffi_type_sint;
+    if ffi_prep_cif(@cif, FFI_REGISTER, 3, @ffi_type_sint, @args[0]) <> FFI_OK then
+    begin
+      WriteLn('ffi_prep_cif failed');
+      Halt(1);
+    end;
+    a := 2;
+    b := 3;
+    vals[0] := m;
+    vals[1] := @a;
+    vals[2] := @b;
+    ffi_call(@cif, ffi_fn(m.MethodAddress('sum')), @rc, @vals[0]);
+    WriteLn('Sum: ', rc);
+{$IFDEF MSWINDOWS}
+    ReadLn;
+{$ENDIF}
+  finally
+    m.Free;
+  end;
+end.
\ No newline at end of file
diff --git a/packages/libffi/fpmake.pp b/packages/libffi/fpmake.pp
index 1d47947e1e..8e189e12b9 100644
--- a/packages/libffi/fpmake.pp
+++ b/packages/libffi/fpmake.pp
@@ -23,8 +23,8 @@ begin
     P.Email := 'libffi-discuss@sourceware.org';
     P.Description := 'Headers for the libFFI library (Foreign Function Interface)';
     P.NeedLibC:= true;  // true for headers that indirectly link to libc?
-    P.OSes := [linux];
-    P.CPUs := [x86_64];
+    P.OSes := [linux,win32,win64];
+    P.CPUs := [i386,x86_64];
     P.Dependencies.Add('rtl-objpas');
 
     P.SourcePath.Add('src');
@@ -36,6 +36,7 @@ begin
 
     P.ExamplePath.Add('examples');
     P.Targets.AddExampleProgram('simple.pp');
+    P.Targets.AddExampleProgram('simpleobj.pp');
 
 {$ifndef ALLPACKAGES}
     Run;
diff --git a/packages/libffi/src/ffi.pp b/packages/libffi/src/ffi.pp
index 208a3a4365..b2b59d98f7 100644
--- a/packages/libffi/src/ffi.pp
+++ b/packages/libffi/src/ffi.pp
@@ -267,7 +267,7 @@ const
 }
 
 const
-  ffilibrary = 'ffi';
+  ffilibrary = {$ifdef mswindows}'libffi-6'{$else}'ffi'{$endif};
 
 {$if defined(CPUX86) and not defined(WIN64)}
   { Note: we can not use FPC_HAS_TYPE_EXTENDED here as libffi won't have the
@@ -285,30 +285,38 @@ type
     elements: ppffi_type;
   end;
 
+{$push}{$macro on}
+ {$ifdef CPU64}
+  {$define extcvar:=cvar external}
+ {$else}
+  {$define extcvar:=external}
+ {$endif}
+{$pop}
+
 var
-  ffi_type_void: ffi_type; cvar; external ffilibrary;
-  ffi_type_uint8: ffi_type; cvar; external ffilibrary;
-  ffi_type_sint8: ffi_type; cvar; external ffilibrary;
-  ffi_type_uint16: ffi_type; cvar; external ffilibrary;
-  ffi_type_sint16: ffi_type; cvar; external ffilibrary;
-  ffi_type_uint32: ffi_type; cvar; external ffilibrary;
-  ffi_type_sint32: ffi_type; cvar; external ffilibrary;
-  ffi_type_uint64: ffi_type; cvar; external ffilibrary;
-  ffi_type_sint64: ffi_type; cvar; external ffilibrary;
-  ffi_type_float: ffi_type; cvar; external ffilibrary;
-  ffi_type_double: ffi_type; cvar; external ffilibrary;
-  ffi_type_pointer: ffi_type; cvar; external ffilibrary;
+  ffi_type_void: ffi_type; extcvar ffilibrary;
+  ffi_type_uint8: ffi_type; extcvar ffilibrary;
+  ffi_type_sint8: ffi_type; extcvar ffilibrary;
+  ffi_type_uint16: ffi_type; extcvar ffilibrary;
+  ffi_type_sint16: ffi_type; extcvar ffilibrary;
+  ffi_type_uint32: ffi_type; extcvar ffilibrary;
+  ffi_type_sint32: ffi_type; extcvar ffilibrary;
+  ffi_type_uint64: ffi_type; extcvar ffilibrary;
+  ffi_type_sint64: ffi_type; extcvar ffilibrary;
+  ffi_type_float: ffi_type; extcvar ffilibrary;
+  ffi_type_double: ffi_type; extcvar ffilibrary;
+  ffi_type_pointer: ffi_type; extcvar ffilibrary;
 {$ifdef HAVE_LONG_DOUBLE}
-  ffi_type_longdouble: ffi_type; cvar; external ffilibrary;
+  ffi_type_longdouble: ffi_type; extcvar ffilibrary;
 {$else}
   ffi_type_longdouble: ffi_type absolute ffi_type_double;
 {$endif}
 
 {$if FFI_TARGET_HAS_COMPLEX_TYPE}
-  ffi_type_complex_single: ffi_type; cvar; external ffilibrary;
-  ffi_type_complex_double: ffi_type; cvar; external ffilibrary;
+  ffi_type_complex_single: ffi_type; extcvar ffilibrary;
+  ffi_type_complex_double: ffi_type; extcvar ffilibrary;
   {$ifdef HAVE_LONG_DOUBLE}
-  ffi_type_complex_longdouble: ffi_type; cvar; external ffilibrary;
+  ffi_type_complex_longdouble: ffi_type; extcvar ffilibrary;
   {$endif}
 {$endif}
 
-- 
2.17.1

silvioprog

2018-10-04 23:10

reporter   ~0111250

Last edited: 2018-10-04 23:10

View 2 revisions

Please, after applying the patch, change the line 290 from:

{$define extcvar:=cvar external}


to:

{$define extcvar:=cvar; external}


Thank you!

Marco van de Voort

2018-11-04 00:01

manager   ~0111767

It removes cvar frm 32-bit non-windows?

silvioprog

2018-11-04 03:10

reporter   ~0111768

Exactly. :-)

Marco van de Voort

2019-06-02 18:12

manager   ~0116534

Why?

Marco van de Voort

2019-12-14 15:45

manager   ~0119844

No reaction for >6Mnths.

Issue History

Date Modified Username Field Change
2018-10-04 22:33 silvioprog New Issue
2018-10-04 22:33 silvioprog File Added: 0001-allows-to-build-ffi-units-on-win32-adds-a-new-exampl.patch.sig
2018-10-04 22:34 silvioprog File Added: 0001-allows-to-build-ffi-units-on-win32-adds-a-new-exampl.patch
2018-10-04 23:10 silvioprog Note Added: 0111250
2018-10-04 23:10 silvioprog Note Edited: 0111250 View Revisions
2018-11-04 00:01 Marco van de Voort Note Added: 0111767
2018-11-04 00:01 Marco van de Voort Assigned To => Marco van de Voort
2018-11-04 00:01 Marco van de Voort Status new => feedback
2018-11-04 03:10 silvioprog Note Added: 0111768
2018-11-04 03:10 silvioprog Status feedback => assigned
2019-06-02 18:12 Marco van de Voort Note Added: 0116534
2019-06-02 20:32 Marco van de Voort Status assigned => feedback
2019-06-02 20:32 Marco van de Voort FPCTarget => -
2019-12-14 15:45 Marco van de Voort Status feedback => resolved
2019-12-14 15:45 Marco van de Voort Resolution open => unable to reproduce
2019-12-14 15:45 Marco van de Voort Note Added: 0119844