Accessing Variables / Constants in an Object from Main Cog. Help Needed.
Dantes Legacy
Posts: 16
Firstly, I am new to the forums but I have been poking about here for over a year now and have gained much help and knowledge. So thanks for all that guys! :thumb:
I have run into a problem with my coding that has me totally stumped. When I try to access a variable or constant from within an object which is defined in the main program or cog, it cannot be done. I should clarify that I am not passing this variable or constant to the object when I call the function from the main cog / object. Also, I know that the problem can be solved by importing all the object code into the main so that it can address that location of program memory easily. I do not wish to do that either. I need to keep the code as neat as I can.
MAIN OBJECT
===========
Now lets say I add a line of code at the end of the 'start' function in the 'FullDuplexSerial' object like so:
Surely there is a way of doing it the other way round? From the object to the main? I have not used any of the assembly commands as of yet with any of my SPIN programming but am more than willing to use it if it will do the job for me. Any help will be greatly appreciated.
Let me know if I have not explained myself fully or you guys need further information.
Thanks.
I have run into a problem with my coding that has me totally stumped. When I try to access a variable or constant from within an object which is defined in the main program or cog, it cannot be done. I should clarify that I am not passing this variable or constant to the object when I call the function from the main cog / object. Also, I know that the problem can be solved by importing all the object code into the main so that it can address that location of program memory easily. I do not wish to do that either. I need to keep the code as neat as I can.
MAIN OBJECT
===========
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Text : "FullDuplexSerial" 'Call Object VAR BYTE Test_Byte 'Set Global Variable Byte PUB MAIN | RXPin, TXPin, Mode, Baudrate RXPin := 1 'Set RS232 pins, mode and baudrate TXPin := 2 Mode := 0 Baudrate := 9600 Text_Byte := "x" 'Set Global Variable To "x" Text.start(RXpin, TXPin, Mode, Baudrate) 'Start a new cog and initialise serial communication
Now lets say I add a line of code at the end of the 'start' function in the 'FullDuplexSerial' object like so:
PUB start(rxpin, txpin, mode, baudrate) : okay '' Start serial driver - starts a cog '' returns false if no cog available '' '' mode bit 0 = invert rx '' mode bit 1 = invert tx '' mode bit 2 = open-drain/source tx '' mode bit 3 = ignore tx echo on rx stop longfill(@rx_head, 0, 4) longmove(@rx_pin, @rxpin, 3) bit_ticks := clkfreq / baudrate buffer_ptr := @rx_buffer okay := cog := cognew(@entry, @rx_head) + 1 ''***EDIT TO ORIGINAL HERE*** tx(Test_Byte)An error will be returned saying that the Propeller Tool expected an expression term when trying to process the 'tx(Test_Byte)' command. I wish to know if there is a way around this WITHOUT passing another variable to the function within the object. I know that within the main cog (or object) I can address variables within the objects like so:
x := ObjectName#VariableName
Surely there is a way of doing it the other way round? From the object to the main? I have not used any of the assembly commands as of yet with any of my SPIN programming but am more than willing to use it if it will do the job for me. Any help will be greatly appreciated.
Let me know if I have not explained myself fully or you guys need further information.
Thanks.
Comments
You have to pass variables or constants to a child object using some subroutine (method) call. You can pass the address of a block of data and then pick out other values relative to the passed address.
Going the other way (from child to parent), you can only reference named constants and subroutines (PUBlic methods). Variables can not be accessed unless you use a subroutine to return the address of a variable or block of variables in the object.
I would recommend making a "wrapper" method in FullDuplexSerial like:
Let's assume you allow backward references from an object to the main (or the code which uses the object - to be more general). People would get used to it and start having backward references more or less often. But what you create then is code which can no longer be used by other programs so easy. The whole object exchange would be full of objects which do not run out of the box, but need all the variables used in backward-references to be added to the main-code.
With the forward references (from main to internals of the object) it's the same but out of a slightly different reason. The author of an object can't change the internals (provide new versions) of the object without interfering with the main program of people using that object.
Actually there is a solution for your problem ... do not use OBJ ... simply cut out the code (for example of the FullDuplexSerial) and copy it into your main-program-file.
Another one is to have a VARIABLES.SPIN with a lot of constants that define the addresses of the variables. Then you can simply access the same variable everywhere you add that object to the OBJ section:
Neither of both methods will create maintainable code and thus it's not really recommended.
@ Magl02 - That is a very good explanation. Thank you very much! Also, great idea about having a 'VARIABLES.SPIN'. I will definitely be using that idea in my future programs. It could come in very useful. Reminds me of header files in C.
Also, not sure if it is a Moderator or Admin who marks these as solved, but go right ahead and do so. Thanks again guys.
If you want to change it to [ solved ] you have to take care about that by yourself by editing the thread.
But as you did not mark it as [ unsolved ] in the beginning you can also leave it as it is.
VARIABLES.SPIN actually is a way how to solve it, but as I said it's not recommended. And especially code that you want to contribute to the object exchange should definitely not use such an approach.