can someone make any sence of this?

Blitz3D Forums/Blitz3D Userlibs/can someone make any sence of this?

Heliotrope(Posted 2010) [#1]
New DLL interface spec
----------------------

1. There is now a directory in the root blitzpath called 'userlibs'.

2. By adding DLLs and '.decls' files to this directory, you can extend blitz's command set.

3. DLLs contain actually library code, while .decls files contain 'declarations' to be added to the
base command set. These declarations describe the functions contained in the Dll.


Format of decls files
---------------------

4. Decls files should always start with a '.lib' directive, followed by the quoted name of the DLL to be
loaded, eg:

5. .lib "mylib.dll"

6. Following the .lib is a list of function declarations. The syntax of these is identical to
function declarations in Blitz, with the following exceptions:

7. * No default parameter values are allowed.

8. * If no function return type is specified, the function is a 'void' function - ie: it returns nothing.

9. * Instead of object parameters, you can only specify 'void*' parameters using a '*' type tag. Such
parameters can be assigned ANY object or bank, so BE CAREFUL!

10. * A declaration may be optionally followed by a 'decorated name'. This takes the form of a ':'
followed by a quoted string denoting the decorated name, eg:

11. MyFunction( text$ ):"_MyFunction@4"
MessageBox%( hwnd,text$,title$,style ):"MessageBoxA"

12. The decorated name is the name of the function as it appears in the dll, and only needs to be
specified if it is different from the actual function name.


Writing DLLs
------------

13. All functions MUST use the _stdcall calling convention.

14. Floats are passed and returned as per standard C/C++ conventions.

15. Strings are passed and returned in 'C' format - ie: a pointer to a null-terminated sequence of
characters.

16. Returned strings must be in a 'static' memory buffer. Once the function returns, this string is
immediately copied into an internal Blitz style string, so its OK to share this buffer between
multiple functions.

17. Both banks and objects can be passed to functions. The value passed is the address of the first byte
of storage. No information is sent regarding the size or type of memory passed so, again, BE CAREFUL!

18. Neither Banks or objects can be returned from functions.

19. Arrays are not supported at all.

20. VisualC decorates symbols quite heavily! If you are coding in 'C', the necessary stdcall specifier
will cause a '_' to be prepended, and a '@' (followed by the number of bytes passed to the function
- ie: number of parameters*4) to be appended. So, something like: 'void _stdcall MyFunc( int x )'
will end up as '_MyFunc@4'. In C++, the name decoration is even messier! But you can supress it by
using the 'extern "C"' feature (see examples below) so you're just left with the 'C' stdcall mess.

21. Other languages such as Delphi and Purebasic don't appear to suffer from this feature, but it can be
worthwhile looking through dll symbols if you're having problems. Check out PEview at
http://www.magma.ca/~wjr Open your dll and select 'SECTION .rdata'/'EXPORT address table'
to have a look at the exported symbols your compiler has seen fit to bestow upon your dll.

Example
-------

22. Ok, here's a little C++ example, as it would appear in VisualC.

23. First, we write the DLL:

24. //demo.dll
//
#include <math.h>
#include <string.h>
#include <stdlib.h>

25. #define BBDECL extern "C" _declspec(dllexport)
#define BBCALL _stdcall

26. //returns a float and has 6 float parameters
BBDECL float BBCALL VecDistance( float x1,float y1,float z1,float x2,float y2,float z2 ){
float dx=x1-x2,dy=y1-y2,dz=z1-z2;
return sqrtf( dx*dx+dy*dy+dz*dz );
}

27. //returns a string and has one string parameter
BBDECL const char * BBCALL ShuffleString( const char *str ){
static char *_buf;

int sz=strlen(str);

delete[] _buf;
_buf=new char[ sz+1 ];
strcpy( _buf,str );

for( int k=0;k<sz;++k ){
int n=rand()%sz;
int t=_buf[k];_buf[k]=_buf[n];_buf[n]=t;
}

return _buf;
}
28. After building this, the resultant 'demo.dll' should be placed in the userlibs directory.

29. Now, we also need to create a 'demo.decls' file, describing the functions in our dll. This file
is also placed in the userlibs directory:

30. .lib "demo.dll"
VecDistance#( x1#,y1#,z1#,x2#,y2#,z2# ):"_VecDistance@24"
ShuffleString$( str$ ):"_ShuffleString@4"

...Voila! The next time Blitz is started up, the new commands appear within the IDE and can be used.

Last edited 2010


Yasha(Posted 2010) [#2]
Those are the instructions from the userlibs folder for creating .decls and .dll files. Except for some reason you've got numbers at the start of each paragraph.

Which part of it is unclear? It looks pretty straightforward, especially if you don't need to make the .dll yourself.


Heliotrope(Posted 2010) [#3]
2. I have not heard of a .decls file, is it .decls, .decl or .dec
4. what is lib
9. what does this mean in english
10-12. I still dont get it
13. what is _stdcall
17. what is ment by an object

Last edited 2010


Yasha(Posted 2010) [#4]
OK...

2. I have not heard of a .decls file, is it .decls, .decl or .dec



A .decls file is a text file with the extension ".decls". This is the file containing the definitions of functions from your DLL. Wrapper DLLs will come with one or more of these, and they also exist for Windows DLLs (in which case you only need this file, as the DLL is already hanging around). You can create a new one with "New Text Document" and rename it by hand; the actual name of the file isn't important, as long as you can remember what it is.

4. what is lib


At the start of the .decls file, there's a directive to tell Blitz which DLL to link to the following function definitions. It takes the following format:

.lib "nameofmydll.dll"

;Followed here by the definitions


You can have more than one of these in the same file, if you want to link different functions to different DLLs. Alternatively, some people also link to an empty set of quotes: this causes the default IDE to highlight that function name, so that libraries written in B3D look better - the effect is only aesthetic (and not necessary if using something like IDEal anyway).

9. what does this mean in english


If you're not very confident with pointers in C or C++, don't touch this one.

It means a type instance or a bank can be passed to a DLL in one of these parameters and Blitz3D will dereference the pointer first (i.e. work some magic so that you get a pointer to the actual data in the bank or type instance, not just an int handle). Passing null or any int that doesn't point to a valid bank will crash everything.

10-12. I still dont get it


In the definitions section of your .decls file, you define functions from your DLL for use in Blitz3D. This takes the following form:

myDLLFunction#(a%, b#, c$) : "_myFunction@12"


On the left is the B3D declaration, showing the name you want to use for it, the return type, and the argument types (and names, so the help bar is useful). This is then followed by a colon. The quoted string after the colon contains the name of the function as it is actually exported by the DLL, which may not necessarily be one you want to use or even a legal B3D function name. Blitz3D now knows to link your references to "myDLLFunction" to the exported function "_myFunction@12".

13. what is _stdcall


You don't need to know this unless you're creating a DLL:

_stdcall is a "calling convention". At the assembly level, things like function calls don't exist; you load up values into registers, jump execution to somewhere else, extend the stack etc. all with separate instructions. A "calling convention" describes the standard order of these operations expected by a function. This is important, because if one function expects to be called with everything already set up, it will break if everything wasn't already set up; similarly if the function calling it expected it to unwind the stack and it didn't, again data will be in the wrong place and things will break.

Normally you don't need to think about this as all functions written with a single compiler use the same calling convention. However, since the whole point of DLLs is to use code written in another language and another compiler, we need to know that the functions will work together at the machine level. Languages like C let you specify calling conventions manually when defining functions, in order to make sure this works.

_stdcall therefore is the calling convention that B3D expects DLLs to use in order to work properly, and anything else is asking for trouble. Most C compilers by default use a different convention called _cdecl, so remembering this step is important for DLL writers.

17. what is ment by an object


An object is an instance of a reference type. i.e. when you create a new instance of a type:

Local a.myType, b.myType

a = New myType
b = a


The data in a can be passed around as a discrete lump and assigned to b, but it's still the same lump of data referenced by a. Because we can throw it around in lumps this way, it can be called an object. If this makes no sense to you, you should read up on B3D's Types first.

Last edited 2010


Heliotrope(Posted 2010) [#5]
cont.

20. what is decorating.
24. is part of the code.