Translating Code to PureBasic

Just starting out? Need help? Post your questions and find answers here.
Elias Montoya
New User
New User
Posts: 8
Joined: Tue May 08, 2007 9:31 pm
Location: Mexico

Translating Code to PureBasic

Post by Elias Montoya »

I just started learning Purebasic and i like it. I still need to get used to
some things but it seems good.

Anyways, my powerbasic dll, works in a way that is perfect in the
powerbasic programming environment, however i dont know how to
do some stuff in Purebasic...

For Example one of the exported functions returns an UDT with several
array pointers, and i can access them from outside the DLL, like this:

Code: Select all

DIM MyArray(ItemNumber) AS LONG AT MemoryPointer
MyArray(3) = 8837
How can i do that In Purebasic? I know i can CopyMemory, im just
trying to avoid that. I think an array can be assigned with a pointer
to a memory block, i was told that, but i dont know how to...

Thanx for any help. :)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Code: Select all

*memoryblock = AllocateMemory(1001 * SizeOf(LONG))  ; Set aside some memory for the array 
Dim MyArray.l(1000)                                 ; Initialize the array 
MyArray() = *memoryblock                            ; Move it to the allocated memory block 

; a test to see that the above snippet worked 
PokeL(*memoryblock+SizeOf(LONG)*3, 8837)            ; Put some data in the memory block to test with 
Debug  MyArray(3)                                   ; Test that it's positioned in the array correctly 
BERESHEIT
Elias Montoya
New User
New User
Posts: 8
Joined: Tue May 08, 2007 9:31 pm
Location: Mexico

Post by Elias Montoya »

Nice! Thanx. Just one question, to assign data to the array i need to do this:

Code: Select all

PokeL(*memoryblock+SizeOf(LONG)*3, 8837)  
?

can i use:

Code: Select all

MyArray(3) = 8837
Directly safely?
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Of course, that first line was only to put a number into the memory block independently of the array so I could read it back from the array element to make sure the array was really moved to the right place.
BERESHEIT
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Thank you both! I was about to ask the same question :)

Peeks and Pokes seem very important in Purebasic, I'm sort of used to looking at the statements as "legacy" from using other compilers that tried to leave those statements back in the dos days but actually they look like the right way to go here.

Have to get used to that as my head is a bit out of sync with the language it seems.
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Peek and poke are good when you absolutely have to use them, but there are other ways using pointers which can be faster.

E.g. consider the following which pokes the value 100 into the 32 bit memory location pointed to by the variable 'mem':

Code: Select all

PokeL(mem, 100)
All well and good.

The following is quicker and uses a pointer to a structure of type LONG:

Code: Select all

*ptr.LONG=mem
*ptr\l = 100
If you're new to Purebasic then this kind of thing can take a little time, but I'm just pointing out that whilst Purebasic does cater for the very 'traditional' ways of doing things, it also has some very nice and slick ways too. :)
I may look like a mule, but I'm not a complete ass.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Srod,

Actually this is what I was getting at, I'm not sure of the PureB pointer syntax. It looks like rather than that it uses peeks and pokes more often but after reading your post I'm not sure anymore.

In the case of your example, is *ptr of some specific type use for pointers? the section on pointers in the docs wasn't really clear.

Is there some more info on "Using pointers in PB" I can read that you know of? When I look at your code I think "is .Long a type defined somewhere with a \l as a member?" :?:

Cheers
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

pdwyer wrote:When I look at your code I think "is .Long a type defined somewhere with a \l as a member?" :?:
Yes. All the Purebasic native types have defined a corresponding structure.; for .w there is the structure .WORD with one member field; namely \w. So the following could be used in place of PokeW() etc.

Code: Select all

*ptr.WORD = mem
*ptr\w = 100
Take a look at the structure viewer in the Purebasic IDE\tools menu.

As for pointers themselves, they are not as 'far reaching' in PB as with some other languages and can essentially only be used as 'pointers to structures'. This means of course in order to have a pointer to a string, for example, you need to define a pointer to a structure of type STRING which has a member variable \s etc.
However, because of this 'simplification' things are a damn sight easier where pointers are concerned and they are just as powerful really. Okay, pointers to pointers require a little fiddling, but it is all very logical. In fact, you will undoubtedly have noticed by now that there is no BY REF command with procedure parameters. All parameters are passed by value. The only way to mimick 'BY REF' is actually to explicitly pass the address of a variable/structure and use a pointer to receive the address:

Code: Select all

Procedure ByRef(*ptr.LONG)
  *ptr\l = 20
EndProcedure

;Define a variable of type long.
  a.l=10

;Output the value of a.  (=10)
  Debug "a = " + Str(a)

;Call the above proc, passing the address of a as a parameter.
ByRef(@a)

;Output the value of a.  (=20)
  Debug "a = " + Str(a)
and I actually find this a very nice way of doing things. Of course you could achieve the above results with Peek and Poke etc. but it's not as nice - or as efficient.

One reason you'll see a lot of Peek's and Poke's is simply because they are often quicker to code when dealing with pointers to pointers and such like. They require more processing however so there is something to be gained by avoiding them where possible.
I may look like a mule, but I'm not a complete ass.
User avatar
blueb
Addict
Addict
Posts: 1111
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Post by blueb »

Take a look at the structure viewer in the Purebasic IDE\tools menu.
Thanks srod.

I hadn't noticed this before... (word being a structure).

I also noticed that if you double-click on any structure it "unfolds" so that you can see each component. This also happens with Interfaces. Nice!

Thanks again,

--blueb
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
Post Reply