Referencing external object from within a library class

Background:
This all started when I thought it would be a really good idea from a program organization viewpoint to move the setup() function from the sketch’s .ino file to a method within a library (class). On a side note I also need to move the current loop() codes as well. Having all the code in one giant file is not practical.

I am not all that fluent in C or C++, older high level languages are more my thing.

When I moved the code in setup() to a subroutine (SetupInLineRoutine) located within the yFiles sketch the sketch compiled and produces the expected result.

Also when I comment (line 11) out the call to Test02.JustASillyInLineRoutine() in SetupRoutine.cpp, the sketch compiled and produces the expected result.

After reinstating line 11, the call to Test02.JustASillyInLineRoutine(), and recompiling I get the following, after removing the full path to shorten the line, compilation error:

Arduino: 1.8.12 (Mac OS X), Board: “Arduino Due (Programming Port)”

/Volumes/…/SketchBook/libraries/SetUpRoutine/SetupRoutine.cpp: In member function ‘int SetupRoutine::JustASillyLibraryRoutine(int)’:
/Volumes/…/SketchBook/libraries/SetUpRoutine/SetupRoutine.cpp:11:3: error: ‘Test02’ was not declared in this scope
Test02.JustASillyInLineRoutine();
^
exit status 1
Error compiling for board Arduino Due (Programming Port).

This report would have more information with
“Show verbose output during compilation”
option enabled in File → Preferences.

What I need to be able to do here is to use a particular object (Test02.JustASillyInLineRoutine()) in the class SetupRoutine which is created in the yFiles.ino sketch.

Do I need to do object creation in some other manner so that any and all methods in all my classes have use of a particular object?

I need some help in determining what I am doing wrong, and subsequently fixing these errors. I has to be a simple mistake, but I am at a loss. I really do not understand what it is trying to tell me other than something is wrong!

I am using the Arduino IDE v1.8.12 under MacOS 10.10.5

The physical file architecture is:

  • For yFiles.ino ← Uses a library call for the subroutine
    Sketchbook/yFiles
    yFiles.ino
    Sketchbook/libraries/TestLib
    TestLib.cpp (contains JustASillyInLineRoutine)
    TestLib.h
    Sketchbook/libraries/SetUpRoutine
    SetupRoutine.cpp (contains JustASillyLibraryRoutine)
    SetupRoutine.h

With a great deal of thanks in advance!

P.S. The expected program result is:
Here I am in a Silly Inline Routine!
Here I am in a Silly Inline Routine!
Here I am in a Silly Library Routine … Flag: 0

ErrorMessage.txt (561 Bytes)

SetupLoopCtrl.cpp (1.47 KB)

SetupLoopCtrl.h (634 Bytes)

TestLib.cpp (1.59 KB)

TestLib.h (744 Bytes)

yFiles.ino (780 Bytes)

Maybe start with My Reply #3 to this Thread.

Thanks for the come back gfvalvo. Really appreciated.

I looked at your reply #3 to the "How to properly include functions written on other sketch tabs" thread.

I think I am doing what you are talking about. I think. After your last suggestion on dealing with global variables by making them external, I did get all that to work.

In this case what I have (I'm trying to use the vocabulary here) is using an instance of a class, i.e. the object "Test01" and its member "JustASillyInLineRoutine" from within another case "SetupRoutine". So I think what I am trying to do is to use Test01.JustASillyInLineRoutine(prtFlag) globally.

So should I be defining/declaring the class TestLib in a separate .h file at the sketch level and the include it everywhere I need it. And it seems that the only place to instantiate the class was at the top of the sketch (yFiles.ino) file.

I am interested in your reference to 'static' directive.

On a side note, I'll check out the Eclipse/Sloeber IDE.

No no no nononono... You're.. Err.. Going the wrong way.

Libraries work well when they are used as building blocks to your main program. You can use them in other ways, but it gets.. complicated.

What I'm reading here is that you would like to move setup() into a library to simplify your life. This is the right basic idea, wrong approach.

Move the bits that pertain to the different libraries over there. Then your setup() gets simpler because it no longer has great big globs of code in it, Just init() or maybe begin() calls to your different libraries. Leave setup() & loop() in your .ino file. Just have the code they call be hidden in the libraries.

You need to think in pictures like this.

       .ino
     /   |   \
libA   libB libC

Then your life will be MUCH easier.

-jim lee

Well, I agree with what you're saying. Perhaps I'd like another layer between .ino and LibA, LibB, LibC. Something like:
yFiles.ino
/
A_setup_routine A_loop_routine

And both A_setup_routine and A_loop_routine use object.methods from LibA, LibB, and LibC.

Am I right in that instantiation takes place at the .ino level?!?!?!? So, I instantiate LibA and LibB, and subsequently try to use an instantiated LibA member inside A_setup_routine. That is when I get the compiler error.

But if I put A_setup_routine in the same physical file as yFiles.ino everything works.

Am I making any sense here?

Oh, I forgot, one more thing. If I do not use intermediate files such as A_setup_routine and A_loop_routine, then setup() and loop() will be literally hundreds of lines of code each.

From a code organization viewpoint I literally have two dozen instantiations of LibA, perhaps two instantiations of LibB, and one instantiation of LibC. Each library providing different functionality.

I know how to do this in plain simple C (if there is such a thing!) but because of the many instantiations of LibA I thought perhaps C++ was the way to go. (I'm learning C++ as I go.) And I do need execution speed. But ......

PeterLev:
I know how to do this in plain simple C ...

It's done exactly the same way with C++ classes. Just think of class instances as another type of variable. If you define an 'int' variable in one file and want to access it in a different file, then in must be global (i.e. declared extern in both the file where it's defined and in every file that wants to access it). Same holds true if the variable is an instance of a class.

BTW, it's critical that you also understand this: What's the difference between declaring and defining in C and C++ - Cprogramming.com

“BTW, it’s critical that you also understand this: What's the difference between declaring and defining in C and C++ - Cprogramming.com
[/quote]”

Yes, I have read that many times. Over and over. It just might be sinking in.

Let me digest your last statement for a bit.

Thanks!!!

gfvalvo:
... Just think of class instances as another type of variable. If you define an 'int' variable in one file and want to access it in a different file, then in must be global (i.e. declared extern in both the file where it's defined and in every file that wants to access it). Same holds true if the variable is an instance of a class.

I'm sorry. I am just not grasping this. If it was a plain variable, then I know to use 'extern int var;' in a global.h file and reference it someplace with 'int var;' statement.

But to me, a function (member) is a whole other thing entirely. I see what your saying, but I do not have a clue on syntax. Does one say 'extern class.member;' That doesn't work. Does one say 'extern int member;' When the member returns an integer. That doesn't seem to work either. Does one try to 'extern class' that certainly does not work.

Sorry.

It's not the member function you treat as a "variable" but the the class instance.

Ok. That was a great hint. But again I am caught up in the syntax. It looks like, based on your hint, if I put a statement such as ‘extern Test02;’ in a file called Global.h after which I include that in yFiles.ino (main) and SetupRoutine.cpp (has the reference to Test02.JustASillyInLineRoutine), the compilation errors I get are:
GlobalStuff.h:15:8: error: ‘Test02’ does not name a type
extern Test02;
^
exit status 1
‘Test02’ does not name a type

I did try different types in the Global.h line ‘extern int Test02;’ I received different errors, but mostly saying:
error: ‘Test02’ has a previous declaration as ‘int Test02’

And so on, and so on for differing types.

So again, apologies for being so dense, but what is the type for the object Test02? From where I sit when one instantiates a class into a particular object, is the resulting object a class? (That doesn’t work.) What kind of thing is it? It is not an integer, float, char, byte, boolean. At the basic level one the question is
extern <what_goes_here?> Test02;

Or is that completely wrong. Btw I tried declaring the entire class external, that did not work either. I received the error “error: a storage class can only be specified for objects and functions”

If I tried extern class Test02; I received the same error. But I thought Test02 was an object.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.