Wanted: userlib tutorial for dummies

Blitz3D Forums/Blitz3D Userlibs/Wanted: userlib tutorial for dummies

jfk EO-11110(Posted 2006) [#1]
One thing that I'm still missing is a tutorial about userlibs that is made for beginners and people who don't know much about the windows api etc.

The very basic stuff should be explained, plus the tricky details should be listed completely. EG: how to send strings, ints,floats, bank adresses, physical adresses from and to a dll. Why do we have to add this ":FunctionNameA" sometimes after the declaration line etc.

If this does not exist at this time then I think it would be welcome.


markcw(Posted 2006) [#2]
well, when it comes to the win32 api you'd need a help file, a tutorial wouldn't be enough.

it would be good to see a tutorial that would expand on the "userlibs_specs.txt" to show more of the basics, like you say, in c++.

it would also be nice to see the same stuff coded in other languages, say c, purebasic and blitzmax.


markcw(Posted 2006) [#3]
Ok, here's a PureBasic example. This shows how to pass an integer, float, string, bank and type.

Create a file in PB called "pbdemo_dll.pb".
Set the file as a dll: Compiler Options > Executable Format > Shared Dll
Copy & paste this code and put the compiled "pbdemo.dll" in the "userlibs" folder.

;pbdemo_dll

;returns a long and has 2 long parameters
ProcedureDLL.l Maximum( nb1.l,nb2.l )
 If nb1>nb2 : result.l=nb1 : Else : result.l=nb2 : EndIf
 ProcedureReturn result
EndProcedure

;returns a float and has 6 float parameters
ProcedureDLL.f VecDistance( x1.f,y1.f,z1.f,x2.f,y2.f,z2.f )
 dx.f=x1-x2 : dy.f=y1-y2 : dz.f=z1-z2
 ProcedureReturn Sqr(dx*dx+dy*dy+dz*dz)
EndProcedure

;returns a string and has 2 string parameters
ProcedureDLL.s AttachString( string1$,string2$ )
 result$=string1$+" "+string2$
 ProcedureReturn result$
EndProcedure

;returns a string and has one string parameter
ProcedureDLL.s ShuffleString( str$ )
 sz.l=Len(str$)
 Dim buf.b(sz)
 For k=0 To sz-1 : buf(k)=Asc(Mid(str$,k+1,1)) : Next k
 For k=0 To sz-1
  n.l=Random(sz-1)
  t.l=buf(k) : buf(k)=buf(n) : buf(n)=t
 Next k
 For k=0 To sz-1 : result$=result$+Chr(buf(k)) : Next k
 ProcedureReturn result$
EndProcedure

;4-bytes structure
Structure rgba
 b.b
 g.b
 r.b
 a.b
EndStructure

;has one pointer and one long parameter
ProcedureDLL SetBankColor( *myptr.rgba,color.l )
 *myptr\b=color & $000000FF
 *myptr\g=(color & $0000FF00) >> 8
 *myptr\r=(color & $00FF0000) >> 16
 *myptr\a=(color & $FF000000) >> 24
EndProcedure

;returns a long and has one pointer parameter
ProcedureDLL.l GetBankColor( *myptr.rgba )
 color.l=*myptr\b & $000000FF
 color=color+(*myptr\g << 8) & $0000FF00
 color=color+(*myptr\r << 16) & $00FF0000
 color=color+(*myptr\a << 24) & $FF000000
 ProcedureReturn color
EndProcedure

;one long and one float structure
Structure test
 a.l
 b.f
EndStructure

;has one pointer, one long and one float parameter
ProcedureDLL SetType( *myptr.test,pa.l,pb.f )
 *myptr\a=pa
 *myptr\b=pb
EndProcedure

;returns a long and has one pointer parameter
ProcedureDLL.l GetTypeA( *myptr.test )
 ProcedureReturn *myptr\a
EndProcedure

;returns a float and has one pointer parameter
ProcedureDLL.f GetTypeB( *myptr.test )
 ProcedureReturn *myptr\b
EndProcedure


Now, you will need to create a "pbdemo.decls" file. Copy & paste the code decls and put this file also in the "userlibs" folder.

.lib "pbdemo.dll"

Maximum%( nb1%,nb2% ):"Maximum"
VecDistance#( x1#,y1#,z1#,x2#,y2#,z2# ):"VecDistance"
AttachString$( string1$,string2$ ):"AttachString"
ShuffleString$( str$ ):"ShuffleString"
SetBankColor( myptr*,rgba% ):"SetBankColor"
GetBankColor%( myptr* ):"GetBankColor"
SetType( myptr*,pa%,pb# ):"SetType"
GetTypeA%( myptr* ):"GetTypeA"
GetTypeB#( myptr* ):"GetTypeB"


Finally, restart Blitz3D and create a new file called "pbdemo_dll.bb". Copy & paste this code and run.

;pbdemo_dll

max = Maximum( 15,30 )
vec# = VecDistance( 0,0,0,1,0,1 )
a$ = AttachString( "PureBasic","Coder" )
s$ = ShuffleString( a$ )

bank = CreateBank(4)
SetBankColor( bank,$ABCDEF )
rgba=GetBankColor( bank )

Type testtype
 Field a,b#
End Type
test.testtype=New testtype
SetType( test,42,12.345 ) ;note: can't pass string fields, causes a MAV
test2.testtype=New testtype
test2\a=GetTypeA( test ) ;note: can't return a type itself, only fields
test2\b#=GetTypeB( test )

Print "max="+max
Print "vec#="+vec#
Print "a$="+a$
Print "s$="+s$
Print "rgba="+Hex(rgba)+" ("+Hex(PeekInt(bank,0))+")"
Print "test\a="+test\a+" test\b#="+test\b#
Print "test2\a="+test2\a+" test2\b#="+test2\b#

WaitKey
End




jfk EO-11110(Posted 2007) [#4]
Yeah, ok, thanks a lot. This is very useful.

What is also needed is information about how to use functions of a dll somebody else used to write.

For example some time ago there was a dll with function names that included the "@" char. How would I have to declare this?

eg: XYDevice@dosomething%(par1,par2...)


For win32 api calls I got a "win32.hlp" file on my computer that is usually helping me to declare win api calls. Additionally I use the Windows Api Constants list that can be found in the archives, cause in win api function descriptions they never tell you the values of those constants, but assume you will use the entire constants defintions in a header file of your c++ project.