Recent

Author Topic: [Solved] Wrong Order of Argument in static calling .DLL in 1.8.2  (Read 3149 times)

nana232

  • New Member
  • *
  • Posts: 40
I used to create .dll file on Lazarus version 1.6.4 and tested it by calling statically. It worked well.
But today I use 1.8.2 and copy the same .dll file (that complied in 1.6.4) to be used in working folder.

Problem #1:
The old .dll file cannot be used. I have to re-complied it again.
I'm not sure there is some minor-chang in compling .dll in the latest version of IDE.
Anyway, the main problem is the next one.

Problem #2:
After the .dll file has been re-complied, it can be used.
But the result from the function is not the same.
It is going negative value.
I found that the problem is .... the wrong order of input argument.

Please see my .dll and Unit1 below:

Code: Pascal  [Select][+][-]
  1. library TestDLL;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes
  7.  
  8. function TestMinus(A,B:double) : double; stdcall;
  9. begin
  10.   result := A-B ;
  11. end;
  12.  
  13. exports
  14. TestMinus;
  15.  
  16. begin
  17. end.
  18.  

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10.   function TestMinus(A,B : double) : double; external 'TestDLL.dll';   //Static Calling .dll
  11.  
  12. type
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   private
  18.  
  19.   public
  20.  
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. procedure TForm1.Button1Click(Sender: TObject);
  31. begin
  32.   Button1.Caption:='A = 5, B =2, Then A - B = ' + FloatToStr(TestMinus(5,2));
  33.   //I got A-B = -3
  34. end;
  35.  
  36. end.
  37.  

From the above codes, I got " A - B = -3".
Is it bug?
« Last Edit: March 18, 2018, 08:56:38 am by nana232 »
Lazarus 1.8.4 Win10 32bit

Awkward

  • Full Member
  • ***
  • Posts: 134
Re: Wrong Order of Argument in static calling .DLL in 1.8.2
« Reply #1 on: March 18, 2018, 05:24:25 am »
About argument order. Maybe define imported function as
function TestMinus(A,B : double) : double; stdcall; external 'TestDLL.dll';   //Static Calling .dll

WooBean

  • Full Member
  • ***
  • Posts: 229
Re: Wrong Order of Argument in static calling .DLL in 1.8.2
« Reply #2 on: March 18, 2018, 07:52:23 am »
I used to create .dll file on Lazarus version 1.6.4 and tested it by calling statically. It worked well.
But today I use 1.8.2 and copy the same .dll file (that complied in 1.6.4) to be used in working folder.

Problem #1:
The old .dll file cannot be used. I have to re-complied it again.
I'm not sure there is some minor-chang in compling .dll in the latest version of IDE.
Anyway, the main problem is the next one.

Problem #2:
After the .dll file has been re-complied, it can be used.
But the result from the function is not the same.
It is going negative value.
I found that the problem is .... the wrong order of input argument.

Please see my .dll and Unit1 below:

Code: Pascal  [Select][+][-]
  1. library TestDLL;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes
  7.  
  8. function TestMinus(A,B:double) : double; stdcall;
  9. begin
  10.   result := A-B ;
  11. end;
  12.  
  13. exports
  14. TestMinus;
  15.  
  16. begin
  17. end.
  18.  

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. ....
  3.  

From the above codes, I got " A - B = -3".
Is it bug?


It must not be true!
Your example is so simple and (after one amendment) gives expected result - line 6. of library TestDLL needs ";" at the end!
This suggests that you sent us something else then compiled by yourself.
In other words, arguments order is not out of order. I TESTED IT FOR 64-BIT CODE!!!

WooBean
« Last Edit: March 18, 2018, 08:49:35 am by WooBean »
Platforms: Win7/64, Linux Mint Ulyssa/64

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Wrong Order of Argument in static calling .DLL in 1.8.2
« Reply #3 on: March 18, 2018, 07:54:35 am »
Indeed, in the code the calling conventions for the dll and the unit external declaration do not match.
Freepascal uses default a fastcall or registercall, which differs from stdcall.
See:
https://www.freepascal.org/docs-html/current/prog/prog.html#QQ2-173-180

The result is as expected: parameters are reversed in your example code.
So it is not a bug. That it happened to work in earlier versions of FPC is because the default calling convention changed.
See the table in the programmers manual, which you could also have examined (rtm).
« Last Edit: March 18, 2018, 08:03:16 am by Thaddy »
Specialize a type, not a var.

WooBean

  • Full Member
  • ***
  • Posts: 229
Re: Wrong Order of Argument in static calling .DLL in 1.8.2
« Reply #4 on: March 18, 2018, 08:16:23 am »
Indeed, in the code the calling conventions for the dll and the unit external declaration do not match.
Freepascal uses default a fastcall or registercall, which differs from stdcall.
See:
https://www.freepascal.org/docs-html/current/prog/prog.html#QQ2-173-180

The result is as expected: parameters are reversed in your example code.
So it is not a bug. That it happened to work in earlier versions of FPC is because the default calling convention changed.
See the table in the programmers manual, which you could also have examined (rtm).


One more, are we in 64-bit or 32-bit environment? I tested proposed code in 64 (manual says that calling modifiers are ignored there for 64-bit dlls). I assumed that the thread starter migrated from 32, so jumped into problem #1.
« Last Edit: March 18, 2018, 08:22:06 am by WooBean »
Platforms: Win7/64, Linux Mint Ulyssa/64

nana232

  • New Member
  • *
  • Posts: 40
Re: Wrong Order of Argument in static calling .DLL in 1.8.2
« Reply #5 on: March 18, 2018, 08:46:02 am »
About argument order. Maybe define imported function as
function TestMinus(A,B : double) : double; stdcall; external 'TestDLL.dll';   //Static Calling .dll


It works.  :)
Thank you
Lazarus 1.8.4 Win10 32bit

nana232

  • New Member
  • *
  • Posts: 40
Re: Wrong Order of Argument in static calling .DLL in 1.8.2
« Reply #6 on: March 18, 2018, 08:47:59 am »
Indeed, in the code the calling conventions for the dll and the unit external declaration do not match.
Freepascal uses default a fastcall or registercall, which differs from stdcall.
See:
https://www.freepascal.org/docs-html/current/prog/prog.html#QQ2-173-180

The result is as expected: parameters are reversed in your example code.
So it is not a bug. That it happened to work in earlier versions of FPC is because the default calling convention changed.
See the table in the programmers manual, which you could also have examined (rtm).

Thank you. :)
Lazarus 1.8.4 Win10 32bit

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Wrong Order of Argument in static calling .DLL in 1.8.2
« Reply #7 on: March 18, 2018, 08:51:33 am »
For completeness:
On the win64 x86_64 platform there is indeed just one calling convention. All others are ignored.
That also means that a dll compiled with stdcall will work on both 32 and 64 bit provided the 32 bit client code also uses stdcall to declare the external method. Same with e.g. cdecl.
So it is safe to use a calling convention in your code provided it is correctly used on 32 bit. On Win64 x86_64 it will just work.
Also note FPC changed the default calling convention in FPC after 1.0.10 so a difference between 2.6.4 and 3.x can not be the issue, at least not with pure pascal code.
Specialize a type, not a var.

nana232

  • New Member
  • *
  • Posts: 40
Re: Wrong Order of Argument in static calling .DLL in 1.8.2
« Reply #8 on: March 18, 2018, 08:53:04 am »
Indeed, in the code the calling conventions for the dll and the unit external declaration do not match.
Freepascal uses default a fastcall or registercall, which differs from stdcall.
See:
https://www.freepascal.org/docs-html/current/prog/prog.html#QQ2-173-180

The result is as expected: parameters are reversed in your example code.
So it is not a bug. That it happened to work in earlier versions of FPC is because the default calling convention changed.
See the table in the programmers manual, which you could also have examined (rtm).


One more, are we in 64-bit or 32-bit environment? I tested proposed code in 64 (manual says that calling modifiers are ignored there for 64-bit dlls). I assumed that the thread starter migrated from 32, so jumped into problem #1.

For Problem#1:
Maybe the different of 32/64bit is a point.
I'm currently using 32bit of 1.8.2.
I remember that it was 1.6.4 - 64bit when compling the dll file.
« Last Edit: March 18, 2018, 08:55:36 am by nana232 »
Lazarus 1.8.4 Win10 32bit

 

TinyPortal © 2005-2018