How to translate from PB PeekI() to C++?

Everything else that doesn't fall into one of the other PB categories.
maslobojik
User
User
Posts: 36
Joined: Thu Jul 11, 2013 11:17 pm

How to translate from PB PeekI() to C++?

Post by maslobojik »

How to translate from PeekI() PokeI() to C++?
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: How to translate from PB PeekI() to C++?

Post by luis »

Assuming you mean integer as in int = 32 bits (else in C you have to use long long int or other definitions depending on what compiler you are using)
http://www.cplusplus.com/doc/tutorial/variables/

So for PB x86, .i = 32 bits, using PeekI/PokeI functions (function calls overhead)

Code: Select all

Define *databuff 
Define i

*databuff = AllocateMemory(512)

i = PeekI(*databuff)

PokeI(*databuff + 10 * SizeOf(Integer), i) ; copy the i value ten integers forward in memory
Using pointers (like you are about to do in C)

Code: Select all

Define *databuff.Integer 
Define i

*databuff = AllocateMemory(512)

; i = PeekI(*databuff)
i = *databuff\i 

; PokeI(*databuff + 10 * SizeOf(Integer), i) 
; PB pointer aritmetic is limited, you have to alter the pointer to move 10 integers forward in memory
; you can't use an expression and immediately use the resulting address in a assignment like in C or like you do with PeekI/PokeI
*databuff + 10 * SizeOf(Integer) 

; now you store the value, remember the pointer is now changed and doesn't point to what returned by AllocateMemory()
*databuff\i = i 

; you can use a temp pointer to copy *databuff to it and alter that one to keep *databuff preserved
Using C pointers

Code: Select all

#include <stdio.h>
#include <stdlib.h>

int main()
{
 int *databuff; /* pointer to int */
 int i; /* int var */
 
 /* cast void pointer (returned from malloc) to int pointer */
 databuff = (int *) malloc(512);
 
 /* in C "*" it's not part of the var name like "*databuff" in PB and it's used to dereference the pointer var "databuff" */
 
 /* i = PeekI(*databuff) */
 i = *databuff;

 /* C pointer arithmetic is "smart", and add 10 times the size of an integer, not 10 bytes */
 printf("%i\n", databuff);
 printf("%i\n", databuff + 10); /* see how much it went forward ? */

 /* PokeI(*databuff + 10 * SizeOf(Integer), i) */
 *(databuff + 10) = i;
}
google pointer arithmetic in C
"Have you tried turning it off and on again ?"
maslobojik
User
User
Posts: 36
Joined: Thu Jul 11, 2013 11:17 pm

Re: How to translate from PB PeekI() to C++?

Post by maslobojik »

Thanks man! It's great answer :)
luis wrote:and add 10 times the size of an integer, not 10 bytes
But how to add 10 bytes to databuffer of int type?
auser
Enthusiast
Enthusiast
Posts: 195
Joined: Wed Sep 06, 2006 6:59 am

Re: How to translate from PB PeekI() to C++?

Post by auser »

In PB we need various PeekA(), PeekB(), PeekC(), PeekL(), PeekI(), PeekQ() and PokeA(), PokeB(), PokeC(), PokeL(), PokeI(), PokeQ() and so on. In C we just need *. The compiler knows the type because we are forced to declare it in C.

That means in C translated to PB (while there is no such function in PB but just to get a clue what C is doing for you):

Code: Select all

C++: *a = *b;
PB: PokeAUTO(*a,PeekAUTO(*b))

So here is some working example with various "Peek" and "Poke" to the same buffer with different types:

Code: Select all

#include <stdio.h>
#include <stdlib.h>

int main()
{
  void *buf;
  int *someints;
  char *somechar;

  buf = malloc(512);
  someints = (int *) buf;
  somechar = (char *) someints;        // or somechar (char *) buf;
  *someints = 2123212321;              // poke int to buf pos 0-3
  *(somechar+4) = 5;                   // poke char to buf pos 4 because type char is one byte
  *(someints+3) = 2123212321;          // poke int to buf pos 12-15 because type int is 4 bytes
  *(somechar+8) = 6;                   // poke char to buf pos 8 because type char is one byte
  *(somechar+9) = 7;                   // poke char to buf pos 9 because type char is one byte
  *(int *) (buf+17) = 2123212321;      // poke int manually to buf pos 17 even if 17 does not fit well as multiple from 4 (int)


  printf("buf pos 0-3 peek as int:   %d\n", *someints);
  printf("buf pos 4 peek as char:    %d\n", *(somechar+4));
  printf("buf pos 4-7 peek as int:   %d\n", *(someints+1));
  printf("buf pos 8 peek as char:    %d\n", *(somechar+8));
  printf("buf pos 8-11 peek as int:  %d\n", *(someints+2));
  printf("buf pos 12 peek as char:   %d\n", *(somechar+12));
  printf("buf pos 12-15 peek as int: %d\n", *(someints+3));
  printf("buf pos 16-19 peek as int: %d\n", *(someints+4));
  printf("buf pos 17-20 peek as int: %d\n", *(int *) (buf+17));
  printf("buf pos 20-23 peek as int: %d\n", *(someints+5));
  printf("buf pos 20 peek as char:   %d\n", *(char *) (buf+20)); // manually as char
  printf("buf pos 20 peek as char:   %d\n", *(somechar+20)); // or because compiler knows it's char

  printf("\n\nBytewise content so far:\n");
  int i;
  for(i=0; i < 24; i++)
    printf("Byte %d: %d\n",i,*(somechar+i));

}
Output:
buf pos 0-3 peek as int: 2123212321
buf pos 4 peek as char: 5
buf pos 4-7 peek as int: 5
buf pos 8 peek as char: 6
buf pos 8-11 peek as int: 1798
buf pos 12 peek as char: 33
buf pos 12-15 peek as int: 2123212321
buf pos 16-19 peek as int: -1918492416
buf pos 17-20 peek as int: 2123212321
buf pos 20-23 peek as int: 126
buf pos 20 peek as char: 126
buf pos 20 peek as char: 126


Bytewise content so far:
Byte 0: 33
Byte 1: -90
Byte 2: -115
Byte 3: 126
Byte 4: 5
Byte 5: 0
Byte 6: 0
Byte 7: 0
Byte 8: 6
Byte 9: 7
Byte 10: 0
Byte 11: 0
Byte 12: 33
Byte 13: -90
Byte 14: -115
Byte 15: 126
Byte 16: 0
Byte 17: 33
Byte 18: -90
Byte 19: -115
Byte 20: 126
Byte 21: 0
Byte 22: 0
Byte 23: 0
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: How to translate from PB PeekI() to C++?

Post by luis »

maslobojik wrote:
luis wrote:and add 10 times the size of an integer, not 10 bytes
But how to add 10 bytes to databuffer of int type?
If the buffer is of int type, you may cast it temporarily to another type (a char) to be able to increment it in 1 byte steps.
Another way it's to use a generic char buffer from the start to have the ability to move around in memory with 1 byte resolution and then to cast it to the appropriate type every time you have to do an operation on it.

Both ways are shown below:

Code: Select all

#include <stdio.h>
#include <stdlib.h>

int main()
{
 int *databuff; /* pointer to int */
 int i = 1234567890; /* int var */
 
 /* cast void pointer (returned from malloc) to int pointer */
 databuff = (int *) malloc(512);
 
/* if you cast the "databuff" pointer to char *, C temporarily consider the size of the data pointed as 1 byte and so it adds just the plain number of bytes you specify, in this case 10 */

 printf("%i\n", databuff);
 printf("%i\n", (char *) databuff + 10); /* see ? it jumps forward just 10 bytes */
  
/* with the following double cast, first you add 10 bytes to the address, and just before assigning an int to that address you cast again the pointer to int * to make the operation acceptable to C */
 
 /* PokeI(*databuff + 10, i) */
 * (int *) ((char *) databuff + 10) = i; 
 
 /* but if you want to move freely in memory, and not by int multiples only you are probably better off using just a char * and to cast it to the right type on every occasion */
 
 char *p;  /* this can move freely with 1 byte resolution */
 
 /* now we transfer to it the pointer of the original allocated buffer */
 p = (char *) databuff;
 
 p += 10; /* we move forward 10 bytes, since it's a pointer to char (byte) */
 
 /* when we want to access an integer at that address, we just inform C about our will with a cast */
 printf("%i\n", * (int *) p);
 
 /* the above should print the 1234567890 int we stored previously in the other more convoluted way */
}
"Have you tried turning it off and on again ?"
maslobojik
User
User
Posts: 36
Joined: Thu Jul 11, 2013 11:17 pm

Re: How to translate from PB PeekI() to C++?

Post by maslobojik »

Thank you very much! The issue is resolved.
Post Reply