Author Topic: Question about prototyped / unprototyped WinApi functions  (Read 3384 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Guest
Question about prototyped / unprototyped WinApi functions
« 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

jcfuller

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #1 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

o2admin

  • Administrator
  • *****
  • Posts: 21
  • OxygenBasic
    • Oxygen Basic
Re: Question about prototyped / unprototyped WinApi functions
« Reply #2 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.


Peter

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #3 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]
« Last Edit: October 23, 2015, 03:20:31 AM by Peter »

Mike Lobanovsky

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #4 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.

Mike Lobanovsky

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #5 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 ...
« Last Edit: October 23, 2015, 04:56:52 AM by Mike Lobanovsky »

Arnold

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #6 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

Peter

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #7 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   

Arnold

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #8 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

Mike Lobanovsky

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #9 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
  • if TextOut() wasn't prototyped, it would expect whole integer (sys, int, long, and/or pointer) arguments
  • BASIC "\" means integer division and "/" means floating-point division
  • integer arithmetics should be used when calc'ing this function's args
  • casts should be used (like you did) if arg calc can't be accomplished through integer arithmetics
  • as the first measure to be taken if TextOut() was prototyped but still fails, go for its prototype, compare it with MSDN, and make sure the author of the header file translated the prototype to BASIC correctly

Charles Pegge

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #10 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)

Mike Lobanovsky

  • Guest
Re: Question about prototyped / unprototyped WinApi functions
« Reply #11 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...