Author Topic: What to expect over the next 5 (or so) days...  (Read 3834 times)

DSMan195276

  • Hero Member
  • *****
  • Posts: 1881
  • Yes
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #15 on: April 18, 2012, 10:02:20 PM »
From my understanding, a .DLL (Or the Linux equivalent, a .SO file) is basically just a headless executable. So, if you were writing a DLL you'd just write the program, but only your SUB's and FUNCTION's would be included in the end program. I imagine there is a compiler option to output a .DLL instead of an executable. The only problem I see is that QB64 shoves all of it's code into it. You're DLL would probably be a few meg's in size to start with. You could in theory do it already though, just go into main.txt, get rid of all the code in main(), and compile with the right option.

I have a feeling that even though this sounds ok, it wouldn't provide good results. Hard to say to be honest.

matt
"He heals the brokenhearted and binds up their wounds." -- Psalm 147:3
QB64 Linux Installer

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4627
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #16 on: April 19, 2012, 02:16:44 AM »
DLL discussion is a bit off-topic. One day, I intend to implement DLL creation in QB64 but there's a lot of groundwork (like modules) to do first.

Here's an example which uses the alternate form of _MEMGET which is a function. Here we turn the memory at the given offset into a STRING of length 10. The STRING type being used here is a bit obscure, usually you'd use a numeric type, but it still works. I'll be attempting to allow user defined types to be used here too, they already work in the _MEMGET sub.
Code: [Select]
SCREEN 13
PSET (0, 0), ASC("H")
PSET (1, 0), ASC("E")
PSET (2, 0), ASC("L")
PSET (3, 0), ASC("L")
PSET (4, 0), ASC("O")
DIM m AS _MEM
m = _MEMIMAGE
x1$ = _MEMGET(m, m.OFFSET, STRING * 5)
PRINT LEN(x1$) 'prints 5
PRINT x1$ 'prints HELLO

Here's a speed example:
Code: [Select]
SCREEN 13
PSET (0, 0), 14
DIM m AS _MEM
m = _MEMIMAGE
DIM o AS _OFFSET
o = m.OFFSET
$CHECKING:OFF
_MEMPUT m, o + 1, _MEMGET(m, o, _BYTE) AS _BYTE
The final line translates into 1 line of C++ code being output:
Code: [Select]
*(int8*)(*__OFFSET_O+ 1 )=*(int8*)(*__OFFSET_O);

Look! _MEM blocks can actually be useful... 8)
Code: [Select]
'here is a screen
SCREEN 13
PSET (0, 0), 123
PSET (1, 0), 222

'here is an array
DIM screen_array(319, 199) AS _UNSIGNED _BYTE

'here's how we can copy the screen to our array
DIM m AS _MEM
m = _MEMIMAGE
_MEMGET m, m.OFFSET, screen_array()

'here's the proof
PRINT screen_array(0, 0) 'print 123
PRINT screen_array(1, 0) 'print 222

And something not so useful, but it does demonstrate using the _MEMGET function to set a user defined type.
Code: [Select]
SCREEN 13
PSET (0, 0), 123
PSET (2, 0), 55
PSET (6, 0), 65
PSET (6 + 9, 0), 66
DIM m AS _MEM
m = _MEMIMAGE

TYPE Happy
    a AS INTEGER
    b AS LONG
    s AS STRING * 10
END TYPE
DIM h AS Happy

h = _MEMGET(m, m.OFFSET, Happy)
PRINT h.a 'prints 123
PRINT h.b 'prints 55
PRINT h.s 'prints "A        B"

Another screen buffering to array test with gimmicks:
Code: [Select]
SCREEN _SCREENIMAGE

_DONTBLEND
PSET (10, 10), _RGBA(50, 100, 200, 128)

TYPE rgba_type
    b AS _UNSIGNED _BYTE
    g AS _UNSIGNED _BYTE
    r AS _UNSIGNED _BYTE
    a AS _UNSIGNED _BYTE
END TYPE

REDIM pixel(_WIDTH - 1, _HEIGHT - 1) AS rgba_type
DIM screen_memory AS _MEM
screen_memory = _MEMIMAGE
_MEMGET screen_memory, screen_memory.OFFSET, pixel()

PRINT pixel(10, 10).r '50
PRINT pixel(10, 10).g '100
PRINT pixel(10, 10).b '200
PRINT pixel(10, 10).a '128
« Last Edit: April 19, 2012, 04:54:44 AM by Galleon »
Something old... Something new... Something borrowed... Something blue...

Clippy

  • Hero Member
  • *****
  • Posts: 16357
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #17 on: April 19, 2012, 07:00:44 AM »
So _MEMIMAGE returns the current SCREEN image buffer values? Can you use a handle value too I gather? 0 would also work? _SOURCE too?

Is _DOT on the horizon?
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4627
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #18 on: April 19, 2012, 07:15:59 AM »
Quote
So _MEMIMAGE returns the current SCREEN image buffer values? Can you use a handle value too I gather? 0 would also work? _SOURCE too?
Yes.


Quote
Is _DOT on the horizon?
It's on the backburner atm.


_MEMFILL allows you to fill blocks of memory with... anything!
syntax: _MEMFILL memory,offset,bytestofill,fillwiththis [AS type]
Code: [Select]
SCREEN _SCREENIMAGE
_FULLSCREEN
DIM m AS _MEM
m = _MEMIMAGE
_MEMFILL m, m.OFFSET, m.SIZE, MKL$(_RGB(255, 255, 0)) + MKL$(_RGB(255, 0, 255)) + MKL$(_RGB(0, 255, 255))
« Last Edit: April 19, 2012, 07:24:38 AM by Galleon »
Something old... Something new... Something borrowed... Something blue...

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4627
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #19 on: April 19, 2012, 10:57:02 PM »
My 3 day coding blitz has been a big success! The _MEM system is now fully implemented and will be available in the next release. It'll take quite a while to release all the details about this new system, but here's a list of the commands and their usage:

Code: [Select]
DIM m AS _MEMThe _MEM type contains the following elements, which are read only:
m.OFFSET 'the offset of the block
m.SIZE 'the size of the block in bytes
m.TYPE 'a group of bits (1=integer, 2=unsigned, 4=floating point, 8=string, 0=unknown/user-defined-type)
m.ELEMENTSIZE 'the size of the elements within the block, a group of INTEGERs would have an element size of 2

---creating and freeing mem blocks---
m = _MEMNEW(size_in_bytes) 'allocates new memory and returns a _MEM block referring to it
m = _MEM(variable) 'returns a _MEM block referring to the largest possible continuous memory region beginning at that variable's offset
m = _MEMELEMENT(variable) 'returns a _MEM block referring to a variable's memory (but not past it)
m = _MEMIMAGE[(image_handle)] 'returns a _MEM block referring to an image's memory
m = _MEM(offset,size_in_bytes) 'creates an unsecure _MEM block referring to the given offset of the given size ***avoid this function if possible***
_MEMFREE m 'ALL mem blocks returned by the above functions MUST be freed

---using mem blocks---
Code: [Select]
CHECKING:OFFUsing CHECKING:OFF before using the following commands significantly increases their speed, removing all overhead and safety to achieve speeds close to or equal to performing the action in assembly language. In general, CHECKING should be left on (the default) during development of a program (for valuable error detection and feedback) but once finished, if speed is important, it should then be set to off.
_MEMCOPY m,m.OFFSET,bytes TO m2,m2.OFFSET
_MEMPUT m,m.OFFSET,variable
_MEMPUT m,m.OFFSET,value AS numeric_type 'stores value in the form of the specificed type
_MEMGET m,m.OFFSET,variable
x = _MEMGET(m,m.OFFSET,type) 'reads the memory location as if it is a particular type
_MEMFILL m,m.OFFSET,bytes_to_fill,variable 'if variable is an INTEGER, it will fill with groups of 2 bytes including using the first half of the integer if there is a remainder
_MEMFILL m,m.OFFSET,bytes_to_fill,value AS numeric_type 'converts value to specified type then fills with that type, again including any non-whole remainder
Code: [Select]
CHECKING:ONDon't forget to set CHECKING back to ON after speed critical sections of code.

---Q & A---

 ???_MEM(variable) vs _MEMELEMENT(variable) ???
Code: [Select]
DIM a(1 TO 10) AS LONG
DIM m AS _MEM
m = _MEM(a(5)): PRINT m.SIZE 'prints 24
m = _MEMELEMENT(a(5)): PRINT m.SIZE 'prints 4

 ???Safety & Security ???
A _MEM type is not memory, it is a reference to memory. Just like a key to a lock for accessing a safe, the _MEM type acts as a key for accessing a region of memory. When CHECKING:ON (on by default) is being used, all _MEM... related commands use this key, which includes hidden 'locking data' within the type. If the memory becomes unavailable (maybe you freed it? maybe it fell out of scope? maybe the array was REDIMed? maybe an image was freed?) then QB64 will report an error and give meaningful feedback, instead of just crashing.
Programs written in other languages don't usually have this feature, they might report a "GPF" or "SegFault" which might be traceable to a line of code in a program but only if a fault is detected, often the offset still points to a valid location which now contains different content still owned by your program, meaning no fault is detected by the OS and the program continues with very unpredictable and possibly damaging results.

 ???Why do I have to use 'm' and 'm.offset' ???
'm' is required when CHECKING:ON is in effect because 'm' contains the 'key' (security information) for the memory region to be accessed. When $CHECKING:OFF is in effect 'm' is totally ignored, so the _OFFSET value (in this case 'm.offset') needs to be absolute, not relative to block 'm'.

Any questions? 8)
« Last Edit: April 20, 2012, 05:16:02 AM by Galleon »
Something old... Something new... Something borrowed... Something blue...

Johny B.

  • Sr. Member
  • ****
  • Posts: 481
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #20 on: April 20, 2012, 04:44:22 AM »
So, if a library wants the address of a 10 byte memory area it can write to and I can read later, can I do:
Code: [Select]
DECLARE LIBRARY "foo"
SUB bar (BYVAL memaddress%&)
END DECLARE

DIM m AS _MEM
m = _MEMNEW(10) 'reserve 10 bytes
bar m.OFFSET 'call the library function

x$ = _MEMGET(m, m.OFFSET, _BYTE) 'read the memory

print x$
_MEMFREE m

P.S Why do we have to pass m and m.OFFSET to things like _MEMGET?

P.P.S Will all allocated memory blocks be freed upon program exit?
"Time is an illusion; Lunchtime doubly so." - Douglas Adams

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4627
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #21 on: April 20, 2012, 05:02:40 AM »
Quote
So, if a library wants the address of a 10 byte memory area it can write to and I can read later, can I do...
A small change to one line (you cannot make a string = a numeric _BYTE type):
Code: [Select]
DECLARE LIBRARY "foo"
SUB bar (BYVAL memaddress%&)
END DECLARE

DIM m AS _MEM
m = _MEMNEW(10) 'reserve 10 bytes
bar m.OFFSET 'call the library function

x$ = _MEMGET(m, m.OFFSET, STRING * 10) 'read the memory

print x$
_MEMFREE m
Also, I've got to congratulate you on putting that code together from scratch without being able to test it. 8)

Spoilers: In a couple of hours you'll be able to try it yourself.

Quote
P.S Why do we have to pass m and m.OFFSET to things like _MEMGET?
'm' is the security key, 'm.offset' is just a value of an _OFFSET type which lies within block 'm'. When $CHECKING:OFF is used the 'm' key is totally ignored, that's why the offset must be an absolute memory offset not an offset relative to the block referred to by 'm'.

Quote
P.P.S Will all allocated memory blocks be freed upon program exit?
Yes.

« Last Edit: April 20, 2012, 05:18:39 AM by Galleon »
Something old... Something new... Something borrowed... Something blue...

Clippy

  • Hero Member
  • *****
  • Posts: 16357
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #22 on: April 20, 2012, 05:20:13 AM »
I'm still trying to picture this. Is there a way to explain what a memory block looks like and how a person would use one? Why they would WANT to use one? Advantages etc. Can you explain the limitations and valid parameters any?

Does _MEMFREE create the same errors as _FREEIMAGE does and can you free all of it?
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4627
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #23 on: April 20, 2012, 06:04:01 AM »
Quote
I'm still trying to picture this. Is there a way to explain what a memory block looks like...
See attached image.

Quote
and how a person would use one? Why they would WANT to use one? Advantages etc.
(i) Moving memory in ways QB64 doesn't cater for without complex, slow workarounds
(ii) Allocating memory regions of various sizes which don't disappear when your SUB/FUNCTION exits
(iii) Allowing a program to pass any type of data to your SUB/FUNCTION (via a _MEM type) and working with that data (using m.TYPE) in an intelligent way
(iv) Speed, did I mention speed?

Quote
Can you explain the limitations?
Quote
valid parameters?
Can you be more specific?

Quote
Does _MEMFREE create the same errors as _FREEIMAGE does and can you free all of it?
If you mean can you free something twice without getting an error, the answer is no. In fact, you'll get a critical error.
Something old... Something new... Something borrowed... Something blue...

Clippy

  • Hero Member
  • *****
  • Posts: 16357
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #24 on: April 20, 2012, 06:33:05 AM »
Is there a way to check a memory area? to check a memory handle value? What range of values are allowed. Can memory handles be freed if they are in use? What type is the memory handle? with m = no type is given.

What kind of problems can memory access create and can they be fixed?

QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4627
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #25 on: April 20, 2012, 06:52:58 AM »
Quote
Is there a way to check a memory area?
No. You need to know in advance if the memory area is still valid before using it. Why not allow this? Because in between you calling the function to check if the memory region is valid and actually using that region the region could (theoretically) be freed by whatever external process you are concerned about. Nor can the later access attempt simply be aborted at point of call if the memory has been freed because if $CHECKING:OFF is in place there is no checking, nothing will be aborted and your program will crash.

Quote
What range of values are allowed.
They are limited only by your system's limitations. As the _OFFSET type will vary in size depending on your computer and OS there is no range as such.

Quote
Can memory handles be freed if they are in use?
A _MEM type is simply a reference to memory, calling _MEMFREE simply removes the reference to that memory not the memory itself. The exception to this rule is memory created with _MEMNEW, that memory is freed by _MEMFREE.

Quote
What type is the memory handle?
type _MEM, that's right, it's not just a simple number it's a group of numbers which make up the 'handle'

Quote
m = no type is given
I've lost you there...

Quote
What kind of problems can memory access create and can they be fixed?
QB64 only lets you access safe memory regions as long as you don't turn $CHECKING:OFF (which is fine to do after testing it works btw) or use the _MEM(offset,size) method to declare a memory region in who knows where.
Something old... Something new... Something borrowed... Something blue...

LeChuck

  • Hero Member
  • *****
  • Posts: 897
  • 18 * 37
Re: What to expect over the next 5 (or so) days...
« Reply #26 on: April 20, 2012, 06:57:58 AM »
Very nice work Galleon, nice coding blitz. 8) I'm gonna test the new _MEM stuff as soon as I'm a little less tired.
Two or more, use a FOR!

Clippy

  • Hero Member
  • *****
  • Posts: 16357
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #27 on: April 20, 2012, 07:01:57 AM »
never mind. m is apparently the memory TYPE

How do we find out our system's limitations or are there known limits by OS?

LeChuck if you are in front of your computer how could you be less tired?
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4627
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #28 on: April 20, 2012, 07:16:39 AM »
Quote
How do we find out our system's limitations or are there known limits by OS?
After calling _MEMNEW, you can check the size of the block it created. If the size or offset is 0 then it failed to allocate the memory.
Something old... Something new... Something borrowed... Something blue...

Clippy

  • Hero Member
  • *****
  • Posts: 16357
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #29 on: April 20, 2012, 07:29:35 AM »
So m = _MEMNEW has the m.SIZE of 0 if the block failed to allocate?


So what ranges of values would each of the type values be?
Quote
m.OFFSET 'the offset of the block
m.SIZE 'the size of the block in bytes
m.TYPE 'a group of bits (1=integer, 2=unsigned, 4=floating point, 8=string, 0=unknown/user-defined-type)
m.ELEMENTSIZE 'the size of the elements within the block, a group of INTEGERs would have an element size of 2

IE: Would the m.OFFSET value be a LONG value?

TYPE would be an integer?

IE: How would the _MEM TYPE look if I made it myself.
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip