Recent

Author Topic: FP Class not compiling in my lazarus app  (Read 5799 times)

J Peasemold Gruntfuttock

  • New Member
  • *
  • Posts: 19
FP Class not compiling in my lazarus app
« on: February 09, 2017, 01:39:05 pm »
This unit is from from my FP application. It doesn't compile when building a Lazarus app, should the declaration be different?

Code: Pascal  [Select][+][-]
  1. // Minimal FreePascal wrapper for sqlite3.dll
  2.  
  3. unit CJHSqlite3;
  4.  
  5. interface
  6. const
  7. //'** Many SQLite functions return an integer result code from the set shown
  8. //'** here in order to indicates success or failure.
  9. //'**
  10. //'** See also: [SQLITE_IOERR_READ | extended result codes]
  11. //'*/
  12. SQLITE_OK          = 0 ; //   ' /* Successful result */
  13. //'/* beginning-of-error-codes */
  14. SQLITE_ERROR       = 1 ; //   ' /* SQL error or missing database */
  15. SQLITE_INTERNAL    = 2 ; //   ' /* NOT USED. Internal logic error in SQLite */
  16. SQLITE_PERM        = 3 ; //   ' /* Access permission denied */
  17. SQLITE_ABORT       = 4 ; //   ' /* Callback routine requested an abort */
  18. SQLITE_BUSY        = 5 ; //   ' /* The database file is locked */
  19. SQLITE_LOCKED      = 6 ; //   ' /* A table in the database is locked */
  20. SQLITE_NOMEM       = 7 ; //   ' /* A malloc() failed */
  21. SQLITE_READONLY    = 8 ; //   ' /* Attempt to write a readonly database */
  22. SQLITE_INTERRUPT   = 9 ; //   ' /* Operation terminated by sqlite3_interrupt()*/
  23. SQLITE_IOERR       = 10; //   ' /* Some kind of disk I/O error occurred */
  24. SQLITE_CORRUPT     = 11; //   ' /* The database disk image is malformed */
  25. SQLITE_NOTFOUND    = 12; //   ' /* NOT USED. Table or record not found */
  26. SQLITE_FULL        = 13; //   ' /* Insertion failed because database is full */
  27. SQLITE_CANTOPEN    = 14; //   ' /* Unable to open the database file */
  28. SQLITE_PROTOCOL    = 15; //   ' /* NOT USED. Database lock protocol error */
  29. SQLITE_EMPTY       = 16; //   ' /* Database is empty */
  30. SQLITE_SCHEMA      = 17; //   ' /* The database schema changed */
  31. SQLITE_TOOBIG      = 18; //   ' /* String or BLOB exceeds size limit */
  32. SQLITE_CONSTRAINT  = 19; //   ' /* Abort due to contraint violation */
  33. SQLITE_MISMATCH    = 20; //   ' /* Data type mismatch */
  34. SQLITE_MISUSE      = 21; //   ' /* Library used incorrectly */
  35. SQLITE_NOLFS       = 22; //   ' /* Uses OS features not supported on host */
  36. SQLITE_AUTH        = 23; //   ' /* Authorization denied */
  37. SQLITE_FORMAT      = 24; //   ' /* Auxiliary database format error */
  38. SQLITE_RANGE       = 25; //   ' /* 2nd parameter to sqlite3_bind out of range */
  39. SQLITE_NOTADB      = 26; //   ' /* File opened that is not a database file */
  40. SQLITE_ROW         = 100; //  ' /* sqlite3_step() has another row ready */
  41. SQLITE_DONE        = 101; //  ' /* sqlite3_step() has finished executing */
  42. //'/* end-of-error-codes */
  43.  
  44. function sqlite3_open(ppath: pChar; var hDB : dword) : longint; cdecl;
  45.  external 'sqlite3' name 'sqlite3_open';
  46. function sqlite3_close(hDB : dword) : longint; cdecl;
  47.  external 'sqlite3' name 'sqlite3_close';
  48. function  sqlite3_get_table(    db: cardinal; sql: pchar; var result: PPCharArray;
  49.                                 var RowCount: Cardinal; var ColCount: Cardinal;
  50.                                 var errmsg: pchar): integer; cdecl;
  51. external 'sqlite3' name 'sqlite3_get_table';
  52. procedure sqlite3_free( pzerms: dword); cdecl;
  53. external 'sqlite3' name 'sqlite3_free';
  54. procedure sqlite3_free_Table( p: dword); cdecl;
  55. external 'sqlite3' name 'sqlite3_free_table';
  56. //
  57. type
  58.     Qlite = class
  59.         public
  60.             hDB                         : dword;    { DB handle }
  61.             sdbpath         : string;   { DB path }
  62.                 SQL                     : string;       { SQL query }  
  63.                 pszerms                 : pchar;        { ptr to error message string }
  64.                 nerror                  : longint;      { error number }
  65.                 nrows                   : longint;      { no of rows in results }  
  66.                 ncolumns                : longint;  { no of columns in results }
  67.                 pQresults       : dword;        { ptr to sqlite's results }
  68.                 function Qlopen (s_in_path : string) : longint;
  69.                 function Qlclose : longint;
  70.             function QlQuery : longint;
  71.         end;
  72.         //
  73.         implementation;
  74.         //     open db identified by spath and return error code
  75.         function Qlopen (s_in_path : string) : longint ;
  76.         begin
  77.                 sdbpath := '';
  78.                 pszerms := nil;
  79.                 SQL := '';
  80.                 hDB := 0;
  81.                 nrows := 0; ncolumns := 0;
  82.                 pQresults := nil;
  83.                 nerror := sqlite3_open( @s_in_path[0], hDB);
  84.                 if nerror = SQLITE_OK then sdbpath := s_in_path
  85.                 QLopen = nerror;
  86.         end;
  87.         //              close db and return error code
  88.         function Qlclose : longint;
  89.                 begin
  90.                         if pszerms <> nil then sqlite3_free( pszerms);
  91.                         if pQresults <> nil then sqlite_free_table(pQresults);
  92.                         if sqlite3_close(hDB) <> SQLITE_OK then
  93.                                 Qlclose := 1;
  94.                 end;
  95.         end;
  96.         // issue query and return sqlite error code
  97.         function QlQuery : longint;
  98.                 if pQresults <> nil then begin
  99.                         sqlite_free_table(pQresults);
  100.                         ncolumns := 0; nrows := 0;
  101.                 end;
  102.                 if pszerms <> nil then begin
  103.                         sqlite3_free( pszerms);
  104.                         nerror := 0;
  105.                 end;
  106.                 QlQuery := sqlite3_get_table( hDB,
  107.                                                                           pChar(SQL),
  108.                                                                           pointer(pQresults),
  109.                                                                           nrows, ncolumns,
  110.                                                                           pChar(pzerms));
  111.         end; {function}
  112.         end; {type}
  113. end.
  114.  
  115.  

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: FP Class not compiling in my lazarus app
« Reply #1 on: February 09, 2017, 02:38:43 pm »
I see extra end; clauses in your code.

J Peasemold Gruntfuttock

  • New Member
  • *
  • Posts: 19
Re: FP Class not compiling in my lazarus app
« Reply #2 on: February 09, 2017, 03:08:10 pm »
Thanks Cyrax, don't think that is the problem.

in http://www.freepascal.org/docs-html/ref/refsu31.html#x81-1030006.5.6 it gives the following example, Let's try that!:
Code: Pascal  [Select][+][-]
  1.  
  2.  
  3.  {$mode objfpc}  
  4. {$h+}  
  5.  
  6. Type  
  7.   TA = Class(TObject)  
  8.   Private  
  9.     class var myprivatea : integer;  
  10.   public  
  11.     class Function GetA : Integer;  static;  
  12.     class Procedure SetA(AValue : Integer); static;  
  13.   end;  
  14.  
  15. Class Function TA.GetA : Integer;  
  16.  
  17. begin  
  18.   Result:=myprivateA;  
  19. end;  
  20.  
  21. Class Procedure TA.SetA(AValue : integer);  
  22.  
  23. begin  
  24.   myprivateA:=AValue;  
  25. end;  

J Peasemold Gruntfuttock

  • New Member
  • *
  • Posts: 19
Re: FP Class not compiling in my lazarus app
« Reply #3 on: February 09, 2017, 03:21:25 pm »
No, that doesn't work, and the error message is not helping!
Code: Pascal  [Select][+][-]
  1. Qlite = class
  2.     public
  3.         hDB                     : dword;    { DB handle }
  4.         sdbpath                 : AnsiString;   { DB path }
  5.         SQL                     : AnsiString;   { SQL query }
  6.         pszerms                 : pchar;        { ptr to error message string }
  7.         nerror                  : longint;      { error number }
  8.         nrows                   : longint;      { no of rows in results }
  9.         ncolumns                : longint;  { no of columns in results }
  10.         pQresults       : dword;        { ptr to sqlite's results }
  11.         function Qlopen (s_in_path : AnsiString) : Longint;
  12.         function Qlclose : longint;
  13.         function QlQuery : longint;
  14.     end;
  15.  
  16.     //
  17.     //     open db identified by spath and return error code
  18.     Class function Qlite.Qlopen (s_in_path : AnsiString) : Longint ;
  19.     begin
  20.         sdbpath := '';
  21.         pszerms := nil;
  22.         SQL := '';
  23.         hDB := 0;
  24.         nrows := 0; ncolumns := 0;
  25.         pQresults := nil;
  26.         nerror := sqlite3_open( @s_in_path[0], hDB);
  27.         if nerror = SQLITE_OK then sdbpath := s_in_path
  28.         QLopen = nerror;
  29.     end;

gets this error message:

Code: Pascal  [Select][+][-]
  1. apossqlite3.pas(80,26) Error: function header doesn't match the previous declaration "Qlopen(AnsiString):LongInt;"

J Peasemold Gruntfuttock

  • New Member
  • *
  • Posts: 19
Re: FP Class not compiling in my lazarus app
« Reply #4 on: February 09, 2017, 03:32:42 pm »
OK, I had "implementation" in the wrong place, the Class procedure definitions must go in implementation after the interface definition.

Thaddy

  • Hero Member
  • *****
  • Posts: 18765
  • To Europe: simply sell USA bonds: dollar collapses
Re: FP Class not compiling in my lazarus app
« Reply #5 on: February 09, 2017, 03:44:02 pm »
OK, I had "implementation" in the wrong place, the Class procedure definitions must go in implementation after the interface definition.

No, the definitions usually go in the interface section if they need to be accessible from outside of the unit and the implementations go in the implementation section.

BTW your initial code can not be compiled with plain FPC either. Same bugs, And same compiler. It is also very badly formatted. If it was properly formatted you would have seen the mistakes much easier yourself.

And note that a method declaration and its implementation indeed *must* match exactly: the compiler told you so....

Next thing is your coding style, that leaves a lot to be desired. (variables in a public class section etc.....)
Why don't you use the standard sqlite3 units from FPC itself? They are much better and will compile to about the same binary code.
Less lines of sourcecode does not mean you binary becomes smaller......
And these standard units have been much better coded and tested than your code. They for one thing have the correct types for the pointers..... NOT dword!!!
« Last Edit: February 09, 2017, 04:02:53 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

jacmoe

  • Full Member
  • ***
  • Posts: 249
    • Jacmoe's Cyber SoapBox
Re: FP Class not compiling in my lazarus app
« Reply #6 on: February 09, 2017, 04:00:52 pm »
Thaddy, in programming, declaration and definition are interface and implementation.

So, declarations go in the type interface section.
Definitions go in implementation section.

This is just wording, but important, because you are not communicating properly at the moment. :)

The way to remember it is to say:
Quote
I declare something that I will define later.

A definition instantiates/implements a declared identifier, and if the definition is missing, the linker will complain about an undefined reference.
« Last Edit: February 09, 2017, 04:42:58 pm by jacmoe »
more signal - less noise

Thaddy

  • Hero Member
  • *****
  • Posts: 18765
  • To Europe: simply sell USA bonds: dollar collapses
Re: FP Class not compiling in my lazarus app
« Reply #7 on: February 09, 2017, 04:06:37 pm »
Thaddy, in programming, declaration and definition are interface and implementation.

So, declarations go in the type section.
Definitions go in implementation section.

This is just wording, but important, because you are not communicating properly at the moment. :)

The way to remember it is to say:
Quote
I declare something that I will define later.

What I wrote is textbook regarding interface and implementation section.. That's not wording that is how it works, with the correct! terminology.
What I added is trying to help. It's bad code, by a beginner, I give some pointers.
- I tested his code and made it not only compile, but made it work. There are so many mistakes in it it is hard to find a place to begin.
- That took a lot more than two or so corrections. It is a mess. People should be told when they cause a mess.
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

jacmoe

  • Full Member
  • ***
  • Posts: 249
    • Jacmoe's Cyber SoapBox
Re: FP Class not compiling in my lazarus app
« Reply #8 on: February 09, 2017, 04:18:00 pm »
Declarations go in 'type' 'interface' and definitions go in 'implementation'.

That is universal lingo across programming languages.

In 'type' 'interface' you declare that something is available, and then define it in the 'implementation' section.

And, yes: I agree that the code is extremely messy.

Edit:
Changed 'type' to 'interface' because the interface (declaration section) can contain more than just types.
« Last Edit: February 09, 2017, 04:42:27 pm by jacmoe »
more signal - less noise

J Peasemold Gruntfuttock

  • New Member
  • *
  • Posts: 19
Re: FP Class not compiling in my lazarus app
« Reply #9 on: February 09, 2017, 05:00:11 pm »
Thank you Thaddy and jacmoe, I haven't written Pascal for decades apart from that little application and I accept your criticsms in a good way.

The error that caused the problem is, I had left the "implementation" word in the wrong place when I edited. Putting it back after the "interface" definition made the compile much happier. Then changing the Class definition to inherit tObject, and prefixing the class method code with Class allowed it to compile.

Dword seems to work fine for pointers in 32-bit world, BTW!

It is comforting to know of the high level of expertise available in these forums. If I was a rich man I would hire you and spend more time selling!

jacmoe

  • Full Member
  • ***
  • Posts: 249
    • Jacmoe's Cyber SoapBox
Re: FP Class not compiling in my lazarus app
« Reply #10 on: February 09, 2017, 05:07:32 pm »
I learned Turbo Pascal in '85, but it wasn't until later - 1997 - that I started to program in earnest. I developed a fully fledged PHP editor in Delph (3, I think) and instantly fell in love with the language!
Then, after the Borland screwup, and the hefty price tag, I went into C and C++ (game development).

A week ago, I went back to Object Pascal, exactly 20 years later. :D
more signal - less noise

 

TinyPortal © 2005-2018