Oxygen Basic

Programming => Problems & Solutions => Topic started by: Arnold on October 22, 2015, 04:38:59 PM

Title: Question about prototyped / unprototyped WinApi functions
Post by: Arnold on October 22, 2015, 04:38:59 PM
Hi Charles,

when modifying the BCX examples I found that I cannot use some kind of compound expressions when I use unprototyped functions, e.g. with TextOut in MinWin.inc or declared prototyped:


  extern lib "GDI32.dll"
...
  ! TextOut             "TextOutA"                '5
...
  end extern


! TextOut lib "gdi32.dll" alias "TextOutA" (sys hdc, int nXStart, int nYStart, char* lpString, int cbString) as bool


...

'xStart=300-(LEN(T_String)*10/2)
  TextOut(hdc,300-(LEN(T_String)*10/2), 15,T_String,LEN(T_String))
xStart=300-(LEN(X_String)*10/2)
  TextOut(hdc,xStart,365,X_String,LEN(X_String))

...


Using TextOut unprototyped the first TextOut statement will show nothing or crash, whereas TextOut prototyped works with both statements. This is not a real problem because I can find out the places in question very fast.

Nevertheless I would like to ask if there are some kind of expressions which are allowed with unprototyped functions or is any expression forbidden in these cases?

Another question: is there a better way to find out if an error occurs with compound expressions in an unprototyped function? At the moment I use print statements combined with console.inc. I also use this code snippet which I found in some Oxygen examples:

  s=error()
  '
  if s then
    print s
    end
  end if

but this seems to effect nothing?

Roland
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: jcfuller on October 23, 2015, 02:04:15 AM
With Patrice a regular visitor, maybe he could provide an O2 example of his excellent ZTrace utility.

James
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: o2admin on October 23, 2015, 02:46:48 AM
Hi Roland,

From running a few tests, I think the problem is using a float division in your unprototyped expressions. This will pass a floating point number instead of an integer.

try using '\' instead of '/'

Currently, The only run-time errors caught by error() are failed identifications of DLL functions.

Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Peter on October 23, 2015, 02:55:53 AM
Hello,
Everything seems Okay!
Code: [Select]
include "asm.inc"
window 640,480,1
hdc = GetBufferDC

Extern lib "GDI32.dll"
! TextOut    "TextOutA"               
End Extern

'! TextOut Lib "gdi32.dll" Alias "TextOutA" (sys hdc, x, y, string lpString, sys nCount) As Long
! SetTextColor Lib "gdi32.dll" (ByVal hdc As Long, ByVal crColor As Long) As Long


string t_string = "what, who, where"
string x_string = "banana, apples, cherries"

SetTextColor hdc,0xFFFFFF
TextOut hdc ,100,100, t_string, len(t_string)
TextOut hdc ,100,120, x_string, len(x_string)

string wrong = error()
if wrong
   mbox "ERROR"
else
   mbox "Okay"
end if   

waitkey
winExit

[attachment deleted by admin]
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Mike Lobanovsky on October 23, 2015, 04:11:36 AM
Peter,

It works OK as long as it passes whole integer arguments:

TextOut sys, sys, sys, ...

or

TextOut sys, sys +|-|*|\ sys, sys +|-|*|\ sys, ...

But it fails with floating point arguments

TextOut sys, sys / sys|float|double, float / sys|float|double, double / sys|float|double, ...

Try

TextOut hdc ,200/2,200/2, t_string, len(t_string)

and it will crash.

Now try

TextOut hdc ,200\2,200\2, t_string, len(t_string)

and it will work.
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Mike Lobanovsky on October 23, 2015, 04:19:08 AM
Charles,

My deepest condolences. Been there, seen that. :)

Splitting the incoming flow of arguments into raw 4-byte chunks and pushing them on stack to call an unprototyped 3rd party function is a real PITA. It's a bottleneck in FBSL BASIC's interpreter where all calls to external DLLs are unprototyped.

I suppose it will also work as expected if you use whatever data types there are for the calculation but then explicitly cast the result to an integer or whatever the function expects its arg to be? (that's what the FBSL BASIC user is supposed to do)

At any rate, the programmer calling a 3rd party function will always look up its help file or MSDN to see what args exactly the function expects. He or she can use this occasion to also put appropriate casts in their places by hand rather than rely on the compiler to do that for them. There are too many bugs in header files out there on the net anyway ...
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Arnold on October 23, 2015, 04:31:44 AM
Hi Charles,

thank you for this solution. I was not aware of a divison problem using floats/single. But using \ instead of / solved everything. So I know where to look in the future.

And I now realize the usefulness of the error() statement too because I often get the unrecognized dll function error when I make a mistake in the declaration. I only was not able to assign these error messages.

Roland
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Peter on October 23, 2015, 05:17:50 AM
Mike,
Code: [Select]
include "asm.inc"
window 640,480,1
hdc = GetBufferDC

Extern lib "GDI32.dll"
! TextOut    "TextOutA"               
End Extern

'! TextOut Lib "gdi32.dll" Alias "TextOutA" (sys hdc, x, y, string lpString, sys nCount) As Long
! SetTextColor Lib "gdi32.dll" (sys hdc, crColor) As Long


string x_string = "WHAT!"

SetTextColor hdc,0x00FFFF
TextOut hdc, int 100/2, int 100/2, x_string, len(x_string)
SetTextColor hdc,0x00FF00
TextOut hdc, int 200\2, int 200\2, x_string, len(x_string)

waitkey
winExit   
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Arnold on October 23, 2015, 07:47:07 AM
Hi Peter,

you applied a cast.

TextOut hdc, 100/2, 100/2, x_string, len(x_string)

will only work with the prototyped function, whereas

TextOut hdc, 100\2, 100\2, x_string, len(x_string)

will work prototyped and unprototyped.

This is of course no problem at all. I now know that I either can do a cast like you did or I can use a prototyped function.

Roland
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Mike Lobanovsky on October 23, 2015, 10:54:02 AM
Exactly, Peter!

It's just a matter of memorizing (and looking up in MSDN, if necessary) that
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Charles Pegge on October 24, 2015, 06:59:19 AM
With function args, Oxygen makes a distinction between cast and convert

If you wnt to pass a float expression or variable, where an int is expected in an unprototyped function:

float f1
...
myfun( hWnd, convert int f1)
Title: Re: Question about prototyped / unprototyped WinApi functions
Post by: Mike Lobanovsky on October 24, 2015, 08:34:35 AM
Thanks, Charles! That must be an important correction. The keyword seems to be missing from the help file, however, along with cast...