Page 1 of 1
DLL needs DOUBLE Values
Posted: Fri Aug 29, 2003 7:56 am
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
Posted: Fri Aug 29, 2003 8:11 am
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]
Posted: Fri Aug 29, 2003 8:35 am
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.
Posted: Fri Aug 29, 2003 12:35 pm
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)
Posted: Fri Aug 29, 2003 1:16 pm
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
Timo
Posted: Sat Aug 30, 2003 12:23 pm
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
Posted: Sat Aug 30, 2003 2:51 pm
by jack
VPureBasic, the DLL is expecting a double, not an integer.
by executing fistp you are storing the value as integer, not double.
Longs serve for DoubleWords
Posted: Sat Aug 30, 2003 7:46 pm
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
Posted: Sat Aug 30, 2003 7:58 pm
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
Posted: Sat Aug 30, 2003 9:41 pm
by jack
incredible!, you take away the 'i' and you have exactly
what i already posted, don't see the point.
Posted: Sun Aug 31, 2003 12:57 am
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
Posted: Mon Sep 01, 2003 7:25 am
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<----------------------
Posted: Mon Sep 01, 2003 7:30 am
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...
Posted: Mon Sep 01, 2003 12:37 pm
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
Posted: Mon Sep 01, 2003 1:45 pm
by clipper

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