DLL needs DOUBLE Values

Just starting out? Need help? Post your questions and find answers here.
clipper
User
User
Posts: 44
Joined: Fri Aug 29, 2003 7:47 am
Location: Germany

DLL needs DOUBLE Values

Post by clipper »

Hallo there,

I´m calling a DLL from PureBasic with
CallFunction(#DLL,"SetDimensions",100,200)
the values 100 and 200 must be given as DOUBLE Values.
How can I do that ?
The declaration of this function in Visual Basic is:
Public Declare Function SetDimensions Lib "derly.dll" (ByVal PageWidth As Double, ByVal PageHeight As Double) As Long

Thank´s a lot for your attention
plouf
Enthusiast
Enthusiast
Posts: 282
Joined: Fri Apr 25, 2003 6:35 pm
Location: Athens,Greece

Post by plouf »

have you try this one ?

Code: Select all

structure Double
  Hi.l
  Lo.l
endstructure 

Var1.double 
Var1\Lo = 100
VAr2.double
Var2\Lo = 200

CallFunction(#DLL,"SetDimensions",Var1,Var2) 
[\code]
Christos
clipper
User
User
Posts: 44
Joined: Fri Aug 29, 2003 7:47 am
Location: Germany

Post by clipper »

I've tried your code but it will not work.
DOUBLE is here a 8Byte float from
-1.79769313486232E308 to -4.94065645841247E-324
other functions without DOUBLE of this dll working fine.
I´ve tested the DLL with VB - everything works fine.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

try this and see if it works.

Code: Select all

Structure double
  a.l
  b.l
EndStructure

Procedure LtoDouble(x.l,*y.double)
! fild dword [esp]
! mov ebx,[esp+4]
! fstp qword [ebx]
EndProcedure

Procedure FtoDouble(x.f,*y.double)
! fld dword [esp]
! mov ebx,[esp+4]
! fstp qword [ebx]
endprocedure
then

Code: Select all

x.double
y.double
LtoDouble(100,@x)
LtoDouble(200,@y)
CallFunction(#DLL,"SetDimensions",x,y)
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

> Public Declare Function SetDimensions Lib "derly.dll" (ByVal PageWidth As Double, ByVal PageHeight As Double) As Long

The double values need to be passed 'ByVal', this means, the actual value
needs to be passed as argument, not the pointer to the value (which would
be 'ByRef')
Passing a structure to a function in PB always passes the pointer, not the
structure itself.

So the call in jacks example should maybe look like this:

Code: Select all

CallFunction(#DLL,"SetDimensions",x\b, x\a, y\b, y\a) 
So the full value goes on the stack. I'm not quite sure about the order
though. maybe the '\a' and '\b' values need to be changed.

I'm not quite sure about this myself. So if jack's code doesn't work, just
give it a try :wink:

Timo
quidquid Latine dictum sit altum videtur
VPureBasic
User
User
Posts: 59
Joined: Fri Apr 25, 2003 6:09 pm
Location: Quebec - Canada

Post by VPureBasic »

Hi All,

Here a code you should try:

Code: Select all

Structure d
       HiValue.l
       LoValue.l
EndStructure

Deftype X.d
Deftype Y.d

Procedure MakeDoubleInteger( LONG.l, ADDRESS.l )
       !FILD   dword [ Esp ]                ; Load integer value
       !MOV   dword Eax, [ Esp + 4 ]   ; Get the address
       !FISTP  qword [ Eax ]               ; Save as double value
EndProcedure

MakeDouble( 100, @X )
MakeDouble( 200, @Y )
CallFunction( #DLL,"SetDimensions", X\HiValue,X\LoValue,   Y\HiValue,Y\LoValue )

Roger
Everything is possible with PureBASIC... All you're missing is imagination!
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

VPureBasic, the DLL is expecting a double, not an integer.
by executing fistp you are storing the value as integer, not double.
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Longs serve for DoubleWords

Post by oldefoxx »

Long are the same size as doublewords, but the uppermost bit is a signed value. That just means that for very loarge values, you have to pass it as a negative value instead of a positive one. You can also define the parameters for the DLL function as having two words passed in place of each double word. The DLL does not know how you declare its functions, nor does it care, just as long as it gets the right values in the right places on the stack when called. So your only concern is to pass the upper and lower word values in the right sequence.

To show you what happens when you use a long, I wrote this little routine to print out an abbreviated power table, where longs are converted into the two word values.

Code: Select all

;Two's Table Generator
;by Donald Darden

;Gives table of powers of 2 for longs And how they translate into dual word
;(doubleword) representations.


OpenConsole()
consolecolor(15,1)
ClearConsole()
a.w=0
b.w=0
c.l=1
x$=""
ConsoleLocate(2,2)
PrintN("Read Table as long = lower, upper word:")
ConsoleLocate(0,4)
Repeat
  MOV eax,c                       ;move variable c into the eax register
  PUSH eax                        ;save it for later  
  MOV a,ax                        ;copy the lower word into variable a 
  ROR eax,16                      ;rotate to get upper eax word into ax reg
  MOV b,ax                        ;save the upper word into variable b 
  x$+"  "+Str(c)+" = "+Str(a.w)+", "+Str(b.w)  ;build the output string
  If Len(x$)>40                   ;see if time to print yet  
    PrintN(x$)                    ;yes, print string 
    x$=""                         ;start string over  
  Else
    x$+Space(40-Len(x$))          ;no, keep building string 
  EndIf
  POP eax                         ;get back original variable c 
  ROL eax,1                       ;rotate it left 1 bit (rotates around)  
  MOV c,eax                       ;save it as the new value for variable c  
Until c=1                         ;see if we have rotated around yet
If x$>""                          ;make sure we print last line
  PrintN(x$)
EndIf  
PrintN("")
PrintN("  Note that word variables are unsigned, so the display of -32768 in the")
PrintN("  above table would be incorrect, and apparently reflects a bug in the")
PrintN("  way PureBasic displays word values.")
Repeat:Until Inkey()>""          ;wait for a key press to end  
CloseConsole()
End
has-been wanna-be (You may not agree with what I say, but it will make you think).
VPureBasic
User
User
Posts: 59
Joined: Fri Apr 25, 2003 6:09 pm
Location: Quebec - Canada

Post by VPureBasic »

Hi,
jack wrote:VPureBasic, the DLL is expecting a double, not an integer.
by executing fistp you are storing the value as integer, not double.
I screwed up for FISTP instead of FSTP... anyways... That's only a mistake about a letter... The code is good if you take it off...


Roger
Everything is possible with PureBASIC... All you're missing is imagination!
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

incredible!, you take away the 'i' and you have exactly
what i already posted, don't see the point.
VPureBasic
User
User
Posts: 59
Joined: Fri Apr 25, 2003 6:09 pm
Location: Quebec - Canada

Post by VPureBasic »

Hi Jack,
jack wrote:incredible!, you take away the 'i' and you have exactly
what i already posted, don't see the point.
Did you read what you code:

Code: Select all

CallFunction(#DLL,"SetDimensions",x,y) 
And I:

Code: Select all

CallFunction( #DLL,"SetDimensions", X\HiValue,X\LoValue,   Y\HiValue,Y\LoValue )
Are you blind are what?!?! Can you see the point this time... We are here to help peoples with their problems not to push people away with sarcasim answer!!!

I do not give advices or tips very often on this forum because of people like U! Thanks to remember me to stay annonymous...

Roger
Everything is possible with PureBASIC... All you're missing is imagination!
clipper
User
User
Posts: 44
Joined: Fri Aug 29, 2003 7:47 am
Location: Germany

Post by clipper »

Yeeees ! Thanks a lot for your help !!

the working code I use now is listen above.
the DLL-output is ok if I use Values like '100'
I can´t use floats like '100.41'



==8<----------------------
Structure double
Hi.l
Lo.l
EndStructure

Procedure MakeDouble( LONG.l, ADDRESS.l )
!FILD dword [ Esp ]
!MOV dword Eax, [ Esp + 4 ]
!FSTP qword [ Eax ]
EndProcedure

Var1.double
Var2.double

MakeDouble( 100, @Var1 )
MakeDouble( 200, @Var2 )

CallFunction(#DLL,"SetDimensions",Var1\Hi,Var1\Lo,Var2\Hi,Var2\Lo )
==8<----------------------
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post by Pupil »

clipper wrote:Yeeees ! Thanks a lot for your help !!

the working code I use now is listen above.
the DLL-output is ok if I use Values like '100'
I can´t use floats like '100.41'
Remove the 'i' in the FILD command and it'll work with floats ;) By doing this the procedure will not produce valid results for long type variables, so you have to go with the two procedures that jack posted earlier, i.e. one procedure for each variable type...
VPureBasic
User
User
Posts: 59
Joined: Fri Apr 25, 2003 6:09 pm
Location: Quebec - Canada

Post by VPureBasic »

Hi clipper,
clipper wrote:Yeeees ! Thanks a lot for your help !!

the working code I use now is listen above.
the DLL-output is ok if I use Values like '100'
I can´t use floats like '100.41'
Just change "LONG.l" to "FLOAT.f" here:
Procedure MakeDoubleFloat( FLOAT.f, ADDRESS.l )
...
...
...
EndProcedure
Roger
Everything is possible with PureBASIC... All you're missing is imagination!
clipper
User
User
Posts: 44
Joined: Fri Aug 29, 2003 7:47 am
Location: Germany

Post by clipper »

:D Many thanks to all coders!
Now it works great and I my DLL eats every value I give her
Post Reply