FB dll for PowerBASIC

New to FreeBASIC? Post your questions here.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FB dll for PowerBASIC

Post by deltarho[1859] »

btw, did you bother to try my example?
No, I didn't - I believed you.<grin>

I will now though so that I can check every aspect of it.

I am going to create a folder and put your method in and St_W's method in for future reference. I will call the folder 'Fruit nightmares'.

This is one aspect of programming that I hate - trying to get an orange to talk to a banana.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FB dll for PowerBASIC

Post by deltarho[1859] »

@srvaldez

Yes, your code works perfectly.

So, St_W's method does not create the barmy @n and your code does but both work - two ways to skin a cat. Of course, my cat is of the Schrödinger variety. I hate cats - give me a dog any day of the week.

Right: A cup of Ceylon, a fine tooth comb and the problem will be throttled. Winston Churchill.

I added a SUB without any parameters and your code, srvaldez, worked a treat. It looks a right dog's dinner but so does St_W's method. On the one hand we have PB's orange becoming a banana and on the other hand we have FB's banana becoming an orange. I wonder if they work on Apple? <sorry>
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FB dll for PowerBASIC

Post by dodicat »

srvaldez
Your example works on WinXP here.
But when I tried my own (some graphics functions in the same way, using alias and stdcall) I get an entry point error.
Have you tried several subs in your dll?
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: FB dll for PowerBASIC

Post by caseih »

deltarho[1859] wrote:PowerBASIC changed hands in January. I have just visited the website and it appears that the free versions are no longer available. I have the previous versions, paid for when they were 'flagship' themselves but, I am sure you will appreciate, I cannot hand them out on a platter because the free versions came with a licence just as the paid for versions. The paid for versions cost less today but they have not been updated for over six years. If I was coming into the market now I would not be parting with any brass. The new owner's intention is to develop new versions and introduce a 64 bit compiler but I, for one, will not be holding my breath. I believe them - they are a US tax software developer and their flagship product is written in PowerBASIC. It is in their interest to develop PB and if they can make money on PB sales as well ... then why not.
Very interesting news. I wish them well. I've always had a soft spot in my heart for PB, as I used their compiler on MS-DOS when I was a teenager.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FB dll for PowerBASIC

Post by deltarho[1859] »

Actually, I am trying to write a CryptoRndII dll.

In FB I have:

Code: Select all

Function CryptoS Alias "CryptoS" As Double Export' [0,1)
In PB I have:

Code: Select all

Declare Function CryptoS LIB "CryptoRndIIDLL.dll" Alias "CryptoS@0" As Double
with a Print CryptoS in PBMain.

In Dependency Walker I have:
Image

The first is a parameter-less Sub. The rest are parameter-less functions except CryptoR which has two Long parameters. Dummy is an exceptionally simple parameter-less function for test purposes, which does not work either.

And yet all I get is a Console window with a flashing cursor and a note from Windows saying it has gone fishing and to close the console at my convenience.

It takes 5 seconds to close!
Last edited by deltarho[1859] on Jul 31, 2017 1:09, edited 1 time in total.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: FB dll for PowerBASIC

Post by caseih »

Perhaps you could post a complete but bare minimal binary example (compiled dll and exe with debugging symbols enabled) that shows this issue for you, perhaps with source code, that others could try, perhaps running it through the visual studio debugger and see if they can replicate the issue and help solve it. A few dummy routines should be enough to demonstrate the issue.

From what you describe, it sounds like there's a mismatch in calling conventions between what PB is expecting and what the DLL is using. Which is a bit odd, since I thought the FB DLL is using stdcall, which is the default in Windows, and you'd think PB would do it that way too. The fact that PB can't recognize symbols with the "@#" appended to them without an alias seems to point to the calling convention being the problem. Could be wrong, though.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FB dll for PowerBASIC

Post by deltarho[1859] »

PB's default is also stdcall.

My head is dropping toward the keyboard - I'll come back to this in the daylight.
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: FB dll for PowerBASIC

Post by srvaldez »

dodicat wrote:srvaldez
Have you tried several subs in your dll?
no, I just did that simple test, and I am fixing to be away from my PC for a day so I don't have the time right now.
@deltarho[1859]
I don't understand why you are having problems, if you upload the dll then perhaps I or someone else can test and try to find the problem, but as for me it will have to wait.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FB dll for PowerBASIC

Post by deltarho[1859] »

srvaldez wrote:I don't understand why you are having problems
What chance have I got then? I can't even see my comfort zone with a telescope.<laugh>

I shall solve this when I am refreshed. I wonder if glass or two of rum will help. I haven't had one of those for ages. Yeah, that must be it.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: FB dll for PowerBASIC

Post by caseih »

Without a minimal, working (or in your case, broken) example to show, you're not likely get any helpful advice here. Like I said, create a small, one-function dummy dll, and a simple PB-generated exe that illustrates the problem (and it sounds like you may have done that already), and post both the binaries and the source. Of course this forum won't allow attachments so you'll have to stick them on dropbox, onedrive or something else. Basically you need to provide something that others can work with and examine themselves. There's got to be a simple explanation and solution, but none of us can say unless you can provide an example we can run.

Although I can't imagine why PB can't deal with stdcall name mangling, you might try putting extern "C" around your FB code. That will prevent the linker from mangling the names. Although I'm not sure this will work anyway, since it might default to cdecl calling convention...
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FB dll for PowerBASIC

Post by deltarho[1859] »

Thanks caseih but "us old folk don't need no stinkin' debuggers" when all we need is a lie-down for a while. Having said that, thanks for the support, guys.

Went to bed and within a few minutes it dawned on me where I was going wrong.

The bas file was being included at the head of whatever application was using it. When we include a bas then any non-passive code gets executed. CryptoRndII requires buffer initialisation and to make sure we do not forget to do that a procedure call was placed in the included bas. Now when we encapsulate a bas into a dll any non-passive code will not get executed - will it Mr Roberts? No. <head bowed>. Of course, with a .a/.bi combo we can have non-passive code in the .bi file.

So, no buffer initialisation was carried out. Now why Windows did not have the common courtesy to present me with a GPF is beyond me. Funny thing is my macro timers require an initialisation and if I forgot in Windows XP and Windows 7 then I invariably got a GPF. Not so in Windows 10. I knew that I had seen this behaviour before but, for the life of me, I could not place it. Remember when a new version of Windows very sneakily got us to the desktop much faster than previous versions even though there was still a pile of stuff to load to make us think that the new version was blindingly fast? Well, may be it is the same with GPFs and Windcows 10. "How can we reduce the number of GPFs?" "Oh, that is easy, stop reporting so many." "Oh, yeah!"

So, I removed the procedure call and exported the procedure passing the responsibility of initialisation to PowerBASIC and it worked. <Eu flaming reka>

CryptoRnd, using threads, was ported to FreeBASIC but CryptoRndII was written in FreeBASIC and uses thread pooling. CryptoRnd was coming in at 45 million singles per second at PowerBASIC which I was 'dead chuffed' with considering PowerBASIC's PRNG was coming in at 80 million singles per second; we are talking about a CPRNG here. CryptoRndII in PowerBASIC is coming in at 105 million singles per second, sticking it's tongue out at the PRNG.

I should add that CryptoRndII in FreeBASIC is coming in at 460 million singles plus per second so is wiping the floor with PowerBASIC. Why? No idea.

So there you have it - senile decay in all it's glory.

@srvaldez

Thanks for your 'stick an alias and export in' and we are good to go. PowerBASIC's Declares look daft with @n but if that is the price we have to pay to get an orange talking to a banana then so be it.

It is good when it comes together. It makes all the grief pale into insignificance, not. <smile>
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FB dll for PowerBASIC

Post by deltarho[1859] »

A little while ago I learned that on some occasions replacing PowerBASIC code with asm was very beneficial but the equivalent FreeBASIC code was best left alone. The above FreeBASIC dll was using FreeBASIC for the Single code. On changing that to asm the Single throughput in PowerBASIC increased from 105 million per second to 321 million per second. That is almost exactly four times faster than PowerBASIC's PRNG.

So much to remember.
St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: FB dll for PowerBASIC

Post by St_W »

deltarho[1859] wrote:A little while ago I learned that on some occasions replacing PowerBASIC code with asm was very beneficial but the equivalent FreeBASIC code was best left alone.
Today's compilers usually are able to optimize the code better than you are able to do yourself on machine code level. That is why using inline assembly for performance reasons does only make sense in very special and rare situations. On the other hand compilers like FreeBasic and probably also PowerBasic only implement a small fraction of the optimizations a modern compiler (like e.g. gcc) would implement. That is why inline assembly did make sense in the past or when not using FB's gcc backend.
What still makes sense and is advisable to think about are higher level optimizations (algorithms, data structures, ...) because compilers usually can't optimize a lot on those high levels.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FB dll for PowerBASIC

Post by dodicat »

Learning some powerbasic does no harm I suppose.
Although, converting simple code from freebasic to powerbasic is very easy.
I suppose they both stem from the old quickbasic anyway.
For anybody interested I have created the graphics dll (originally for C++) for use with powerbasic.

one.bas for the dll

Code: Select all

'one.bas --- a dll for powerbasic or FreeBASIC
'compile with -dll

Sub screen1 alias "screen1"(Byval X As integer, Byval Y As integer,xres as integer,yres as integer,b as integer) EXPORT
  Screenres xres,yres,b
  SCREENCONTROL(100, X, Y)
End Sub

sub clearcolor alias "clearcolor"(c as ulong) export
    color ,c
    cls
    end sub

function rgbcolor alias "rgbcolor"(r as long,g as long,b as long) as ulong export
    return rgb(r,g,b)
end function

Sub drawstring alias "drawstring"(x as long,y as long, text As zstring ptr,c as ulong) EXPORT
 draw string (x,y),*text,c
End Sub

sub printdbl alias "printdbl"(n as double,flag as long=0) export
    select case as const flag
    case 0:print n
    case 1:print n,
    case 2:print n;
    case else
        print n
        end select
    end sub

sub line1 alias "line1"(x1 as long,y1 as long,x2 as long,y2 as long,c as ulong) EXPORT
    line (x1,y1)-(x2,y2),c
end sub

sub sleep1 alias "sleep1"(t as long) export
    sleep t 
end sub

sub waitkey alias "waitkey" export
    sleep
end sub

function randoms alias "randoms"(n as long) as double export
    return rnd*n
    end function

sub circlefill1 alias "circlefill1"(x1 as long,_
    y1 as long,_
    rad as long,_
    c as ulong) export
    circle (x1,y1),rad,c,,,,f
end sub

sub circle1 alias "circle1"(x1 as long,_
    y1 as long,_
    rad as long,_
    c as ulong) export
    circle (x1,y1),rad,c
end sub

sub pset1 alias "pset1"(x1 as double,y1 as double,c as ulong,im as any pointer=0) EXPORT
    pset im,(x1,y1),c
end sub

sub clearscreen1 alias "clearscreen1" export
    cls
end sub

sub endkey1 alias "endkey1"export
    if inkey=chr(27) then end
end sub

sub screenlock1 alias "screenlock1"export
    screenlock
end sub

sub screenunlock1 alias "screenunlock1" export
    screenunlock
end sub

sub getmouse1 alias "getmouse1"( mx as long ptr, my as long ptr, mw as long ptr, mb as long ptr) export
    getmouse(*mx,*my,*mw,*mb)
end sub
sub locate1 alias "locate1"(x as long,y as long) export
    locate x,y
end sub

Function framecounter alias "framecounter" As long export
    dim as double t2=timer
    Static As Double t3,frames,answer
    frames=frames+1
    If (t2-t3)>=1 Then
        t3=t2
        answer=frames
        frames=0
    End If
    Return answer
End Function

Function regulate alias "regulate"( MyFps As long, fps As long ptr) As long export
    Static As Double timervalue,lastsleeptime,t3,frames
    frames+=1
    If (Timer-t3)>=1 Then t3=Timer:*fps=frames:frames=0
    Var sleeptime=lastsleeptime+((1/myfps)-Timer+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    lastsleeptime=sleeptime
    timervalue=Timer
    Return sleeptime
End Function


 
And the powerbasic code:

Code: Select all

#Compile Exe
#Dim All
  

Declare Sub screen1 StdCall Lib "one.dll" Alias "screen1@20"(ByVal x As Integer, ByVal y As Integer, ByVal xres As Integer, ByVal yres As Integer, ByVal b As Integer)
Declare Sub drawstring StdCall Lib "one.dll" Alias "drawstring@16"(ByVal x As Long, ByVal y As Long, ByVal TEXT As String Pointer, ByVal c As Long)
Declare Sub printdbl StdCall Lib "one.dll" Alias "printdbl@12"(ByVal n As Double, ByVal flag As Long)
Declare Sub circlefill1 StdCall Lib "one.dll" Alias "circlefill1@16"(ByVal x1 As Long, ByVal y1 As Long, ByVal rad As Long, ByVal c As Long)
Declare Sub circle1 StdCall Lib "one.dll" Alias "circle1@16"(ByVal x1 As Long, ByVal y1 As Long, ByVal rad As Long, ByVal c As Long)
Declare Function rgbcolor StdCall Lib "one.dll" Alias "rgbcolor@12"(ByVal r As Long, ByVal g As Long, ByVal b As Long) As Long
Declare Sub screenlock1 StdCall Lib "one.dll" Alias "screenlock1@0"()
Declare Sub screenunlock1 StdCall Lib "one.dll" Alias "screenunlock1@0"
Declare Sub sleep1 StdCall Lib "one.dll" Alias "sleep1@4"(ByVal n As Long)
Declare Function randoms StdCall Lib "one.dll" Alias "randoms@16"(ByVal n As Long) As Double
Declare Sub clearscreen1 StdCall Lib "one.dll" Alias "clearscreen1@0"
Declare Sub endkey1 StdCall Lib "one.dll" Alias "endkey1@0"
Declare Sub locate1 StdCall Lib "one.dll" Alias "locate1@8"(ByVal x As Long, ByVal y As Long)
'declare sub getmouse1 StdCall Lib "one.dll" Alias "getmouse1@16"(byval mx as long ptr, byval my as long ptr, byval mw as long ptr, byval mb as long ptr)
Declare Function regulate StdCall Lib "one.dll" Alias "regulate@8"(ByVal myfps As Long, ByVal fps As Long Ptr) As Long
Declare Sub clearcolor StdCall Lib "one.dll" Alias "clearcolor@4"(ByVal c As Long)
'end extern

    Type ball
       x As Single
       y As Single
       dx As Single
       dy As Single
       col As Long
  End Type

  Sub move_(b() As ball)
    Dim n As Integer
    For n =0 To 2
  b(n).x=b(n).x+b(n).dx:b(n).y=b(n).y+b(n).dy
    Next n
End Sub

 Sub edges(b() As ball )
  Dim r As Long
  r=50
  Dim n As Integer
    For n =0 To 2
  If(b(n).x<r) Then b(n).dx=-b(n).dx
     If(b(n).x>1000-r)Then b(n).dx=-b(n).dx
    If(b(n).y<r)Then b(n).dy=-b(n).dy
    If(b(n).y>768-r)Then b(n).dy=-b(n).dy
    Next n
End Sub

 Sub draw_(b() As ball )
   Dim n As Integer
     For n =0 To 2
  circlefill1(b(n).x,b(n).y,50,b(n).col)
    circle1(b(n).x,b(n).y,50,rgbcolor(255,255,255))
    Next n
End Sub

  Sub BallCollisions(b() As ball)
  Dim L As Single
  Dim impulsex As Single
  Dim impulsey As Single
  Dim dot As Single
  Dim impactx As Single
  Dim impacty As Single
  Dim n1 As Integer
  Dim n2 As Integer
    For n1 =0 To 2
        For n2 =n1+1 To 2
    L=Sqr( (b(n1).x-b(n2).x)*(b(n1).x-b(n2).x) + (b(n1).y-b(n2).y)*(b(n1).y-b(n2).y))
      If (L<100) Then
       impulsex=(b(n1).x-b(n2).x)/L
       impulsey=(b(n1).y-b(n2).y)/L
       b(n1).x=b(n2).x+100*impulsex
       b(n1).y=b(n2).y+100*impulsey
       impactx=b(n1).dx-b(n2).dx
       impacty=b(n1).dy-b(n2).dy
       dot=impactx*impulsex+impacty*impulsey
       b(n1).dx=b(n1).dx-dot*impulsex
       b(n1).dy=b(n1).dy-dot*impulsey
       b(n2).dx=b(n2).dx+dot*impulsex
       b(n2).dy=b(n2).dy+dot*impulsey
   End If
Next n2
Next n1

End Sub




Function PBMain () As Long
Dim  b(0 To 2) As ball
Dim fps As Long
Dim  sleeptime As Long
Dim  mx As Long
Dim my As Long
Dim  mw As Long
Dim  mb As Long
   Dim st As String
   st=" Press escape key to end"
   Dim st2 As String
   st2=" Framerate"
     b(0).x = 100
  b(0).y = 100
  b(0).dx = 5.2
  b(0).dy = 3.2
  b(0).col = rgbcolor(0, 100, 200)
  b(1).x = 600
  b(1).y = 200
  b(1).dx = -5.2
  b(1).dy = 3.2
  b(1).col = rgbcolor(200, 100, 0)
  b(2).x = 700
  b(2).y = 500
  b(2).dx = -1.2
  b(2).dy = 3.2
  b(2).col = rgbcolor(0, 200, 0)
  screen1(50, 20, 1000, 768, 32)
  clearcolor(rgbcolor(0, 0, 100))
  While 1
    move_(b())
    edges(b())
    BallCollisions(b())
    screenlock1()
    clearscreen1()
    draw_(b())
    drawstring(50, 10, StrPtr(st), rgbcolor(255, 200, 0))
    drawstring(0, 55, StrPtr(st2), rgbcolor(0, 200, 0))
    locate1(8, 11)
    printdbl(fps, 0)
    screenunlock1()
    sleeptime = regulate(65, VarPtr(fps))
    sleep1(sleeptime)
    endkey1()
  Wend
  

End Function 
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FB dll for PowerBASIC

Post by deltarho[1859] »

St_W wrote:That is why using inline assembly for performance reasons does only make sense in very special and rare situations.
I disagree. With double precision, in the above, we need 2x32 bits. In this case replacing FreeBASIC with asm was very beneficial. So, as we move from simplicity to complexity we move from BASIC to asm. I doubt that it could be determined, a priori, where the cross over point is. So, if performance is an issue then it would be expedient to consider both BASIC and asm. The operative phrase is, of course, "if performance is an issue".

PowerBASIC is not an optimising compiler which may explain why asm is faster than BASIC for both single precision and double precision, in the above. With FreeBASIC's gcc backend asm was only faster for double precision, in the above.

In general, I would guess, for performance issues, I will find FreeBASIC's inline assembler being commissioned less often than PowerBASIC's inline assembler.

Being a hobbyist I have the luxury of being able to waste time at no real cost. A commercial programmer, on the other hand, needs to be very clear whether a particular piece of code is a performance issue or not.

@dodicat
I suppose they both stem from the old quickbasic anyway.
They do.

Well done on your PowerBASIC code. I haven't got the time to consider it in depth. You have 'end extern in there. I always read your FreeBASIC code as I almost invariably learn something new. It was only last week that I thought "Now what is he doing".<laugh>
Post Reply