Page 3 of 4

Posted: Mon Jan 30, 2006 12:28 am
by Intrigued
I will be utilizing such in a .dll, with ProcedureDLL. Is there anything that needs to changed? As I want to have a .dll utilized by by another application building platform.

TIA and for the suggestions.

Posted: Wed Feb 01, 2006 3:13 am
by Intrigued
*A hush befalls the auditorium*

:wink:

Posted: Wed Feb 01, 2006 5:43 am
by Guimauve
Sorry if I'm late on this topic but a Structure can be manipulated like this :

Code: Select all

; 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure definition >>>>>

Structure Test

     a.l
     b.l

EndStructure

; <<<<<<<<<<<<<<<<<<<<
; <<<<< Mutators >>>>>

Procedure SetTesta(*ObjetA.Test, a.l)

     *ObjetA\a = a

EndProcedure

Procedure SetTestb(*ObjetA.Test, b.l)

     *ObjetA\b = b

EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Observators >>>>>

Procedure.l GetTesta(*ObjetA.Test)

     ProcedureReturn *ObjetA\a

EndProcedure

Procedure.l GetTestb(*ObjetA.Test)

     ProcedureReturn *ObjetA\b

EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Update operator >>>>>

Procedure UpdateTest(*ObjetA.Test, a.l, b.l)

     SetTesta(*ObjetA, a)
     SetTestb(*ObjetA, b)

EndProcedure
When you built a set of command to access the structure you will save time if you need to modify the structure, Name of Field or Structure it's self.

Code: Select all

Structure Test
   
   Array.l[2]
   
EndStructure

; <<<<<<<<<<<<<<<<<<<<
; <<<<< Mutators >>>>>

Procedure SetTesta(*ObjetA.Test, a.l)
   
   *ObjetA\Array[0] = a
   
EndProcedure

Procedure SetTestb(*ObjetA.Test, b.l)
   
   *ObjetA\Array[1] = b
   
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Observators >>>>>

Procedure.l GetTesta(*ObjetA.Test)
   
   ProcedureReturn *ObjetA\Array[0]
   
EndProcedure

Procedure.l GetTestb(*ObjetA.Test)
   
   ProcedureReturn *ObjetA\Array[1]
   
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Update operator >>>>>

Procedure UpdateTest(*ObjetA.Test, a.l, b.l)
   
   SetTesta(*ObjetA, a)
   SetTestb(*ObjetA, b)
   
EndProcedure
I hope this small exemple can help some of you.

Regards

Guimauve

Posted: Thu Feb 02, 2006 12:16 am
by Intrigued
Thanks Guimauve! I'm off to print and study such.

Thanks again!

Posted: Thu Feb 02, 2006 12:56 am
by Intrigued
I believe after all is said and done that the parent (not PB) application I am using to develop certain .exes with just can not handle anymore returns than just one. I would like to have multiple return values, I have been using .exe builds with command-line args. to facilitate such. But I would like to be able to parse multiple variables from a ProcedureReturn call.

I may be SOL?

Posted: Sat Feb 04, 2006 10:29 pm
by Kale
Heres a simple way that multiple values can be returned by a procedure:

Code: Select all

Procedure.l MakePoints(Value.l)
    Static Coords.POINT
    Coords\x = Value & $FFFF
    Coords\y = (Value >> 16) & $FFFF
    ProcedureReturn @Coords
EndProcedure

*Screen.POINT = MakePoints(67109632)

Debug *Screen\x
Debug *Screen\y
Using a structure pointer is simple.

1. Use a static structure inside your procedure
2. manipulate it and return its pointer
3. fill another structure using a pointer

:wink:

Posted: Sun Feb 05, 2006 2:15 am
by Intrigued
Thanks Kale, I'm goint to take off my dunce hat and practice with this code.

Thanks again.

Posted: Sun Feb 05, 2006 4:04 am
by Intrigued
Hmmm... I wanted to see what @Coords was holding (that's the part I need to have more than one variable returning) and it shows only one number when I did this:

Code: Select all

MessageRequester("", Str(@Coords))
Sooo... it seems I'm not understanding how this is actually returning more than one variable.

Can you dumb it down for me Kale, when you get a moment.

TIA (dunce hat going back on, I know, I know)

:x

:wink:

Posted: Sun Feb 05, 2006 5:16 am
by Dare2
Hi Intrigued,

If you don't mind me butting in until Kale gets back to the boards -

If I understand correctly, you are using PureBasic to write supporting functionality which will be compiled into a DLL. This DLL will be used by an app developed in another language, or perhaps using something that creates apps (such as GameMaker).

If so, then if the other language supports (a) structures and (b) memory addresses, you can pass multiple values via a structure. If not, you will have to make multiple calls to get the values.

Assuming it does, you create a structure (and your parent app needs an equivalent structure, or type, or record, whatever terminology it uses) and a procedure that handles the support function workload.

Code: Select all

Structure myStuff
  myLong.l
  myDoubleWord.l
EndStructure

ProcedureDLL getMyStuff(*itIsMine.myStuff)
  *itIsMine\myLong=-1
  *itIsMine\myDoubleWord=1
EndProcedure
The above receives, from the parent, the address where your data is to be stored, and fills in the results.

The call would be along these lines:

Code: Select all

alsoMine.myStuff
getMyStuff(@alsoMine)
Debug alsoMine\myLong
Debug alsoMine\myDoubleWord
Except, of course, using the syntax of the parent app, and however that calls a DLL - and with the parent app having a structure/type that matches your PureBasic structure/type.

If you lump those two bits of code together for PureBasic, you will see the values you want to see. Changing them in the procedure to validate.

That is one way (you give the proc the address) and many api calls use this.

Another is that the procedure returns an address to you. This leaves the DLL with a chunk of memory it has to maintain "state" with, so I prefer the first.

I hope that helped. I also hope I was on track, as it can be frustrating to be told what you already know .. :)

Posted: Sun Feb 05, 2006 6:02 am
by Intrigued
Dare2 wrote:Hi Intrigued,

If you don't mind me butting in until Kale gets back to the boards -

If I understand correctly, you are using PureBasic to write supporting functionality which will be compiled into a DLL. This DLL will be used by an app developed in another language, or perhaps using something that creates apps (such as GameMaker).

If so, then if the other language supports (a) structures and (b) memory addresses, you can pass multiple values via a structure. If not, you will have to make multiple calls to get the values.

Assuming it does, you create a structure (and your parent app needs an equivalent structure, or type, or record, whatever terminology it uses) and a procedure that handles the support function workload.

Code: Select all

Structure myStuff
  myLong.l
  myDoubleWord.l
EndStructure

ProcedureDLL getMyStuff(*itIsMine.myStuff)
  *itIsMine\myLong=-1
  *itIsMine\myDoubleWord=1
EndProcedure
The above receives, from the parent, the address where your data is to be stored, and fills in the results.

The call would be along these lines:

Code: Select all

alsoMine.myStuff
getMyStuff(@alsoMine)
Debug alsoMine\myLong
Debug alsoMine\myDoubleWord
Except, of course, using the syntax of the parent app, and however that calls a DLL - and with the parent app having a structure/type that matches your PureBasic structure/type.

If you lump those two bits of code together for PureBasic, you will see the values you want to see. Changing them in the procedure to validate.

That is one way (you give the proc the address) and many api calls use this.

Another is that the procedure returns an address to you. This leaves the DLL with a chunk of memory it has to maintain "state" with, so I prefer the first.

I hope that helped. I also hope I was on track, as it can be frustrating to be told what you already know .. :)
I appreciate your help. The other development platform I am using these PB created .dlls for does not allow direct access to memory. What happens is that there is an "Action" (aka. procedure) that calls the .dll. Then we pass in the Function name to the Action and any arguments. The return is set into a Global variable we can use inside our programs. The setback I found out is that it seems I can only get one return variable from a PB .dll to that other development platform. Either it's a number (Long) or a String. I want to be able to get more than one variable back from the .dll. This will help fill in the holes that the other development platform has.

So, I am using PB to help expand the other platform via .dlls is what I'm muttering on about.

:-D

I hope that helps?

Another idea I just thought of was to have the (what a hack job this will be though) .dll create a temp file and then have the other development platform app. read in that data into a couple different variables.

Uhg! I wish I could just access memory with that other platform.

*pulls ears till pain sets in*

ps. I see your "multiple calls" idea. aka. multiple functions... er Procedure use I take it? Hmmm... that actually sounds like the way I might have to go, or better way to go. Thanks for you help!

Posted: Sun Feb 05, 2006 6:16 am
by Dare2
Ouch.

If the number is small enough, and there a few enough :) perhaps you could fill the long. Eg, up to 4 x 1 byte, 2 x 2 byte, etc. So (v1 << 24) + (v2 << 16) + (v3 << 8 ) + v4, as an example (for vals 0-255).

Or use the string?

Does it have a good way of getting substrings. Eg an Array = Split(String,character) or StringField type approach? If so, perhaps you could fill a string with Str(r1) + "," + Str(r2) [+ ....]

Otherwise, I pass. Sorry!

Posted: Sun Feb 05, 2006 6:24 am
by Intrigued
Dare2 wrote:Ouch.

If the number is small enough, and there a few enough :) perhaps you could fill the long. Eg, up to 4 x 1 byte, 2 x 2 byte, etc. So (v1 << 24) + (v2 << 16) + (v3 << 8 ) + v4, as an example (for vals 0-255).

Or use the string?

Does it have a good way of getting substrings. Eg an Array = Split(String,character) or StringField type approach? If so, perhaps you could fill a string with Str(r1) + "," + Str(r2) [+ ....]

Otherwise, I pass. Sorry!
If this helps it uses the LUA language as it's scripting engine. There are something like 600 Actions (they call them Actions, instead of functions) innate to the platform. But, I have used "pure" LUA code inside of my apps. Also, I have seen there is a LUA library for PB. I wonder if that would help any. More... "hmmm" :D

Posted: Sun Feb 05, 2006 6:35 am
by Dare2
Aha, for this we need * drumroll * FloHimself.

He is a genius with this, and seems pretty easy going and helpful so I don't think it would be out of line to PM him.

However it also seems like you're cracking into the workarounds. Success to you!

Posted: Sun Feb 05, 2006 6:47 am
by Intrigued
Dare2 wrote:Aha, for this we need * drumroll * FloHimself.

He is a genius with this, and seems pretty easy going and helpful so I don't think it would be out of line to PM him.

However it also seems like you're cracking into the workarounds. Success to you!
Thanks again for your help. It's helped me look at the situation in a different light.

*thumbs up*

Posted: Sat Feb 18, 2006 12:26 am
by FloHimself
Intrigued wrote:The other development platform I am using these PB created .dlls for does not allow direct access to memory. What happens is that there is an "Action" (aka. procedure) that calls the .dll...
Just discovered this thread and haven't read all... but sounds to me you
are trying to write something like a *lua extension* with PB?