View Issue Details

IDProjectCategoryView StatusLast Update
0013891FPCCompilerpublic2011-05-01 17:49
ReporterElphi Assigned ToMarco van de Voort  
PrioritynormalSeverityblockReproducibilityalways
Status closedResolutionno change required 
Product Version2.2.2 
Summary0013891: Firebird udf library routines return garbage on Linux i386 platforms
DescriptionEnclosed is a testlibrary with two simple routines. Tested with a host compiled with Lazarus/fpc both routines work properly on win32 and lin32. Tested with Firebird as host only on win32 I get proper results. The library build with default compiler options parameters on fc10 and tested on the same platform with Firebird returns proper results for routine VV, but NULL for Y_Odd. On CentOS 5.3 both routines fail returning -1218650452 and 0 resp.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId0
FPCTarget
Attached Files

Activities

2009-06-02 11:57

 

libtestfb.lpr (321 bytes)

Robert Gilland

2009-06-09 22:40

reporter   ~0028412

I need this to work as well.

Marco van de Voort

2009-06-10 11:58

manager   ~0028437

Last edited: 2009-06-10 11:58

Does it matter if you remove "CONST"? Keep in mind that const in Pascal might not be the same as CONST in C/C++.

Jonas Maebe

2009-06-10 12:09

manager   ~0028439

> Keep in mind that const in Pascal might not be the same as CONST in C/C++.

It does for cdecl.

Elphi

2009-06-15 20:26

reporter   ~0028559

Checked; doesn't make any difference.
Looks like a routine like
function DoStr(AStr: PChar): integer; cdecl; export
seem to work, whereas functions with an integer input parameter like
function DoInt(AInt: Integer): integer; cdecl; export
do not.

Marco van de Voort

2009-06-15 22:01

manager   ~0028560

Well, here you use integer, in the attached example you use "longint" ?

Integer can be 16-bit depending on mode (TP,FPC), and 32-bit on more delphi oriented modes (objfpc,delphi)

Jonas Maebe

2009-06-15 22:07

manager   ~0028561

It's best to use the ctypes unit and then types such as cint to make sure that you are using the same types on the C and Pascal side.

It's still odd that pchar parameters would work while integer parameters don't, because they are passed in exactly the same way with all calling conventions supported by FPC that I know of (including cdecl).

Elphi

2009-06-16 08:43

reporter   ~0028569

Last edited: 2009-06-16 08:45

Marco, I used integer as a general representation of the 16, 32 and 64 bit integer types I've tested.
Jonas, I've tested your suggestion using cint16, cuint16, cint32, cuint32, cint64 and cuint64 for the simple VV function in mode objfpc, and in all cases wrong results were returned.

Marco van de Voort

2009-06-27 13:16

manager   ~0028796

Elphi: can you think about a tutorial how to set up FB and test things like that?

Preferably on both. It doesn't have to be perfect, just something I can use to test a bit on FC-11 on a rainy afternoon.

Elphi

2009-06-29 19:53

reporter   ~0028861

Ok, coming soon...

2009-07-02 21:21

 

testudf.txt (2,387 bytes)   
// The udf library for testing, compiled with default Lazarus 0.26.2 / fpc 2.2.2 settings
(*
library libtestfb;

{$mode delphi}{$H+}

uses
  Classes;

function Y_Odd(const AValue: integer): integer; cdecl; export;
begin
  if Odd(AValue) then
    Result := -1
  else
    Result := 0;
end;

function VV(AValue: integer): integer; cdecl; export;
begin
  Result := AValue;
end;

function is_cheque(s: PChar): integer; cdecl; export;
var
  p: PChar;
begin
  Result := 0;

  if (strlen(s) = 0) or (strlen(s) > 6) then exit;

  p := s;
  while p^ <> #0 do
  begin
    if not (p^ in ['0'..'9']) then exit;
    Inc(p);
  end;

  Result := 1;
end;

exports

Y_Odd,
VV,
is_cheque;

begin
end.
*)

// Log in as root and install Firebird using yum:
# yum install firebird
// The sql server is fully installed and running as a service listening to port 3050.

// Copy the test module with udf functions into firebird's UDF directory:
# cp /pathto/libtestfb.so /usr/lib/firebird/UDF

// We will use the isql command line tool for testing (docu: http://www.destructor.de/firebird/isql.htm):
# cd /usr/lib/firebird/bin
# ./isql
Use CONNECT or CREATE DATABASE to specify a database
// We get a SQL prompt waiting for commands
// like connecting as system administrator sysdba to the (local) sample database employee using the default password masterkey:
SQL> connect employee user sysdba password masterkey;
Database:  employee, User: sysdba
// We need to register the udf's with the database:
SQL> declare external function is_cheque cstring(255) returns integer by value entry_point 'is_cheque' module_name 'libtestfb';
SQL> declare external function Y_Odd integer returns integer by value entry_point 'Y_Odd' module_name 'libtestfb';
SQL> declare external function VV integer returns integer by value entry_point 'VV' module_name 'libtestfb';
// Now we are ready for testing:
SQL> select is_cheque('123456') from rdb$database;

   IS_CHEQUE 
============ 
           1 

SQL> select is_cheque('12345Z') from rdb$database;

   IS_CHEQUE 
============ 
           0 

// is_cheque works as expected.

SQL> select Y_Odd(1) from rdb$database;

       Y_ODD 
============ 
           0 

SQL> select Y_Odd(2) from rdb$database;

       Y_ODD 
============ 
           0 

SQL> select VV(13) from rdb$database;

          VV 
============ 
 -1077851028 

// Both Y_Odd and VV return garbage.

SQL> exit;
#


testudf.txt (2,387 bytes)   

Elphi

2009-07-02 21:28

reporter   ~0028905

Added testudf.txt for instructions on how to install Firebird on Fedora and test some simple udf's.
I added a routine is_cheque which takes a string input parameter, and works as expected.

Maybe it is easier to test the module calling routines from a c/c++ program, as Firebird is written in c++.

Joost van der Sluis

2010-07-22 10:25

manager   ~0039591

Could be that this is fixed in trunk now with the calling-convention fixes. Can you try?

Jonas Maebe

2010-07-22 10:39

manager   ~0039594

The calling convention fixes were only for x86-64, so normally this won't change anything about linux/i386...

Chris Gradussen

2010-12-02 22:47

reporter   ~0043902

The solution is simple

Change the CONST in the example to VAR and it works like a charm.

So
function Y_Odd(const AValue: LongInt): LongInt; cdecl; export;

will be

function Y_Odd(var AValue: LongInt): LongInt; cdecl; export;

Regards Chris

Chris Gradussen

2010-12-02 22:50

reporter   ~0043903

Sorry,

Tested with Lazarus Ide v0.9.28.2-8ubuntu1 Beta 32 bits
(Default Lazarus from Ubuntu 10.04.1)

If necessary I can test with the 64 bit version.

Please let me know, then I have to reconfigure some machines.

Jonas Maebe

2010-12-02 22:55

manager   ~0043905

Does that mean that the C declaration also contained "const int*" rather than "const int" ?

Chris Gradussen

2010-12-02 23:29

reporter   ~0043907

Last edited: 2010-12-02 23:31

I believe so,

And if you write it down on that way I really think I can remember that!

But it is very long ago. I wrote udfs with kylix in 2002(fpc and lazarus dit not use the dpr extension for projects though?). To do that I used documentation for delphi and there you already had to use the VAR because in firebird the params where threated as pointers. And indeed with (the char* (PChar)) I did not use the VAR clause.
However I did not use it for linux for 8 years, but as the libs in linux are upgraded for the last 8 years and the old kylix code did not work anymore I had to recompile my code to use it again on linux.

I hope it helps you and I'm happy that finally I can do a little back for the lazarus/fpc community.

Chris Gradussen

2010-12-03 13:21

reporter   ~0043940

For a reference see this link

http://www.firebirdsql.org/index.php?op=useful&id=geldenhuis

So

yes cont int*

Jonas Maebe

2010-12-04 13:51

manager   ~0043979

Thanks for the follow-up.

Issue History

Date Modified Username Field Change
2009-06-02 11:57 Elphi New Issue
2009-06-02 11:57 Elphi File Added: libtestfb.lpr
2009-06-09 22:40 Robert Gilland Note Added: 0028412
2009-06-10 11:58 Marco van de Voort Note Added: 0028437
2009-06-10 11:58 Marco van de Voort Note Edited: 0028437
2009-06-10 12:09 Jonas Maebe Note Added: 0028439
2009-06-15 20:26 Elphi Note Added: 0028559
2009-06-15 22:01 Marco van de Voort Note Added: 0028560
2009-06-15 22:07 Jonas Maebe Note Added: 0028561
2009-06-16 08:43 Elphi Note Added: 0028569
2009-06-16 08:45 Elphi Note Edited: 0028569
2009-06-27 13:16 Marco van de Voort Note Added: 0028796
2009-06-29 19:53 Elphi Note Added: 0028861
2009-07-02 21:21 Elphi File Added: testudf.txt
2009-07-02 21:28 Elphi Note Added: 0028905
2010-07-05 12:38 Marco van de Voort Status new => assigned
2010-07-05 12:38 Marco van de Voort Assigned To => Marco van de Voort
2010-07-22 10:25 Joost van der Sluis Note Added: 0039591
2010-07-22 10:39 Jonas Maebe Note Added: 0039594
2010-12-02 22:47 Chris Gradussen Note Added: 0043902
2010-12-02 22:50 Chris Gradussen Note Added: 0043903
2010-12-02 22:55 Jonas Maebe Note Added: 0043905
2010-12-02 23:29 Chris Gradussen Note Added: 0043907
2010-12-02 23:31 Chris Gradussen Note Edited: 0043907
2010-12-03 13:21 Chris Gradussen Note Added: 0043940
2010-12-04 13:51 Jonas Maebe Status assigned => resolved
2010-12-04 13:51 Jonas Maebe Resolution open => no change required
2010-12-04 13:51 Jonas Maebe Note Added: 0043979
2011-05-01 17:49 Marco van de Voort FPCOldBugId => 0
2011-05-01 17:49 Marco van de Voort Status resolved => closed