Variables as references/pointers? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Guest

Variables as references/pointers?

30 Mar 2015, 01:06

Heya,

I was wondering if there is a way for a variable/member of a object to act as a reference or a pointer?

Here's an example:

Code: Select all

g_MYVAR := 20
class MyClass
{
    myVarA := ByRef g_MYVAR ;doesnt work
    __new(ByRef myVar)
    {
        global
        
        this.myVarB := myVar ;doesn't work either
        this.myVarC := ByRef g_MYVAR ;nope
        this.myVarD := &myVar ;I can get the address but how do I retrieve the content?
        
        myVar += 20
        
        msgbox % "<g_MYVAR:" g_MYVAR ">, <myVarA:" this.myVarA ">, <myVarB:" this.myVarB ">, <myVarC:" this.myVarC ">, <myVarD:" this.myVarD ", " &myVar ", " &g_MYVAR ">" 
    }
}
msgbox % "Before new class: " g_MYVAR
t_MyClass := new MyClass(g_MYVAR)
msgbox % "After new class: " g_MYVAR
exitapp
Thank you very much!
Elgin
Posts: 124
Joined: 30 Sep 2013, 09:19

Re: Variables as references/pointers?  Topic is solved

30 Mar 2015, 04:45

If I understand you correctly you want changes to the reference variable in the method to affect the global variable and all other references to it. If that's it, then using an object as the global variable is probably the simplest solution:

Code: Select all

g_MYVAR := Object()
g_MYVAR["SomeValue"] := 20

class MyClass
{
    myVarA := g_MYVAR 
    __new(myVar)
    {
        global
       
        this.myVarB := myVar 
        this.myVarC := g_MYVAR 
        this.myVarD := &myVar 
       
        myVar["SomeValue"] += 20
       
        msgbox % "<g_MYVAR:" g_MYVAR["SomeValue"] ">, <myVarA:" this.myVarA["SomeValue"] ">, <myVarB:" this.myVarB["SomeValue"] ">, <myVarC:" this.myVarC["SomeValue"] ">, <myVarD:" this.myVarD["SomeValue"] ", " myVar["SomeValue"] ", " g_MYVAR["SomeValue"] ">"
    }
}
msgbox % "Before new class: " g_MYVAR["SomeValue"]
t_MyClass := new MyClass(g_MYVAR)
msgbox % "After new class: " g_MYVAR["SomeValue"]
exitapp
Guest

Re: Variables as references/pointers?

30 Mar 2015, 09:20

I want to be able to retrieve the content of a global var (g_MYVAR in that case) through a object's member. That way, if I have to change a non-static global I don't have to update all objects.

Basically I just want the object's member to act as a C pointer or a reference.

Something like:

Code: Select all

#include <string>

int g_MYINT_A = 0;
int g_MYINT_B = 1;

struct foo
{
	int* number;

	foo(int& r)
	{
		number = &r;
	}

	//foo(int* p) //also valid
	//{
	//	number = p;
	//}

	void say()
	{
		printf("Number is %d!\n", *number);
	}
};

int main(int argc, char **argv){
	foo* foo1 = new foo(g_MYINT_A);
	foo* foo2 = new foo(g_MYINT_B);
	foo* foo3 = new foo(g_MYINT_B);

	g_MYINT_A++;
	g_MYINT_B += 5;

	foo1->say(); //print 1
	foo2->say(); //print 6
	foo3->say(); //print 6

	g_MYINT_B--;

	foo2->say(); //print 5
	foo3->say(); //print 5

	while (true);
}
Guest

Re: Variables as references/pointers?

30 Mar 2015, 09:27

Elgin wrote:...
Thanks for the reply, I'll check out the solution!
Coco-guest

Re: Variables as references/pointers?

30 Mar 2015, 09:45

Note sure if this is what you need:

Code: Select all

g_Hello := "Hello World"
hello := new Test(g_Hello)
MsgBox % hello.Value
g_Hello := "Goodbye World!!"
MsgBox % hello.Value

class Test
{
	__New(ByRef v)
	{
		this.__Ptr := &v
	}

	Value {
		get {
			return StrGet(this.__Ptr, A_IsUnicode ? "UTF-16" : "CP0")
		}
	}
}
Coco-guest

Re: Variables as references/pointers?

30 Mar 2015, 11:43

Referencing a global variable (via its address as shown in my previous post) is unreliable. Assigning an object to the global variable changes its address, that is this.__Ptr != &g_Variable, so there is no way to keep track of it. Might as well use a custom object that acts as a variable:

Code: Select all

g_Var := new Variable("Hello World") ; initialize, assign value
MsgBox % "Value: " . g_Var.Value . "`nType: " . g_Var.Type . "`nCapacity: " . g_Var.Capacity

g_Var.Value := 123 ; assign integer
MsgBox % "Value: " . g_Var.Value . "`nType: " . g_Var.Type . "`nCapacity: " . g_Var.Capacity

; use var as struct
g_Var.Capacity := 16 ; set capacity, RECT
DllCall("GetWindowRect", "Ptr", A_ScriptHwnd, "Ptr", g_Var[]) ; address of buffer
RECT := Format("
(Join`r`n
Script's Main Window RECT
Left:   {}
Top:    {}
Right:  {}
Bottom: {}
)", NumGet(g_Var[], 0, "Int"), NumGet(g_Var[], 4, "Int"), NumGet(g_Var[], 8, "Int"), NumGet(g_Var[], 12, "Int"))
ListVars
ControlSetText, Edit1, %RECT%, ahk_id %A_ScriptHwnd%
WinWaitClose ahk_id %A_ScriptHwnd%
return

class Variable
{
	__New(value)
	{
		this.__Value := value
	}

	__Get(key:="", args*)
	{
		if !key
			return ObjGetAddress(this, "__Value") ; blank if there is no string buffer
	}

	Value {
		get {
			return this.__Value
		}
		set {
			return this.__Value := value
		}
	}

	Type {
		get {
			return IsObject(this.Value)   ? "Object"
			     : this.Capacity != ""    ? "String"
			     : InStr(this.Value, ".") ? "Float"
			     :                          "Integer"
		}
	}

	Capacity[FillByte:=0] {
		get {
			return ObjGetCapacity(this, "__Value")
		}
		set { ; emulate VarSetCapacity(), that is to always clear the buffer
			if (this.Type != "String")
				this.__Value := "" ; assign string or else address is blank
			ObjSetCapacity(this, "__Value", 0) ; free buffer first
			ObjSetCapacity(this, "__Value", value) ; set new capacity
			DllCall("RtlFillMemory", "Ptr", this[], "UPtr", value, "UChar", FillByte) ; fill memmory
		}
	}
}
Coco-guest

Re: Variables as references/pointers?

30 Mar 2015, 12:05

I forgot to mention the most important thing in relation to your post - you just simply assign the variable object to another variable to get a strong reference: ref := g_VariableObject, ref.Value := newValue ; updates real time.
Plus you can create base classes for different variable types by subclassing:

Code: Select all

str := new String("Hello")
MsgBox % str.Value
str.Value := 123 ; throws an error, invalid value

class String extends Variable
{
	__New(string)
	{
		this.Value := string
	}

	Value {
		set {
			if (ObjGetCapacity([value], 1) == "")
				throw Exception("Value must be string", -1, string)
			return base.Value := value
		}
	}
}
lexikos
Posts: 9641
Joined: 30 Sep 2013, 04:07
Contact:

Re: Variables as references/pointers?

30 Mar 2015, 18:40

I think you're overcomplicating it.

Code: Select all

g_MYVAR := 20
class MyClass
{
    __new(myVarName)
    {
        this._myVar := myVarName
		
		this.myVar += 20
    }
	myVar {
		get {
			local v := this._myVar
			return (%v%)
		}
		set {
			local v := this._myVar
			return (%v% := value)
		}
	}
}
msgbox % "Before new class: " g_MYVAR
t_MyClass := new MyClass("g_MYVAR")
msgbox % "After new class: " g_MYVAR
exitapp
(Only works with global variables.)
I Apologize

Re: Variables as references/pointers?

18 Apr 2015, 12:52

I could've sworn I posted "Thank you everybody!" but I didn't.

Thanks a lot everbody!

Sorry for the necro.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: CodeKiller, GEOVAN and 180 guests