Communication between multiple windows

hello. I am new to OF and C++ but not to programming (migrating from Processing). I have provided a MCVE based on the ‘multiWindowExample’ (without the use of ofxGui). I am just trying to pass strings between windows just to get started. I was able to reference a string variable from the second window in the main window but not vice-versa. I know I am missing something fundamental here. I have commented out and noted with an arrow the three lines in the code that are the final failed attempt at solving this problem.

main.cpp:

#include "ofMain.h"
#include "ofApp.h"
#include "Window2.h"
#include "ofAppGLFWWindow.h"

//========================================================================
int main() {
	ofGLFWWindowSettings settings;

	settings.setSize(300, 300);
	settings.setPosition(glm::vec2(0, 0));
	settings.resizable = true;
	shared_ptr<ofAppBaseWindow> secondWindow = ofCreateWindow(settings);

	settings.setSize(1920, 1080);
	settings.setPosition(glm::vec2(1920, 0));
	settings.resizable = true;
	shared_ptr<ofAppBaseWindow> mainWindow = ofCreateWindow(settings);

	shared_ptr<Window2> secondApp(new Window2);
	shared_ptr<ofApp> mainApp(new ofApp);
	mainApp->secWindow = secondApp;
	//secondApp->mainWindow = mainApp;       <----------

	ofRunApp(secondWindow, secondApp);
	ofRunApp(mainWindow, mainApp);
	ofRunMainLoop();

}

ofApp.h:

#pragma once

#include "ofMain.h"
#include "Window2.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y );
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void mouseEntered(int x, int y);
		void mouseExited(int x, int y);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);

		string mainString;

		shared_ptr<Window2> secWindow;
		
};

ofApp.cpp:

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

	ofSetFrameRate(60);
	ofSetVerticalSync(true);
	ofBackground(0);
	mainString = "main window";

}

//--------------------------------------------------------------
void ofApp::update(){
}

//--------------------------------------------------------------
void ofApp::draw(){
	stringstream ss;
	ss << "framerate: " << ofToString(ofGetFrameRate(), 0) << endl;
	ss << "mainString: " << mainString << endl;
	ss << "secondString: " << secWindow->secondString << endl;   //works
	ofDrawBitmapString(ss.str().c_str(), 20, 20);
}

Window2.h:

#pragma once

#include "ofMain.h"

class Window2 : public ofBaseApp
{
public:
	void setup();
	void update();
	void draw();

	string secondString;
	
	//shared_ptr<ofApp> mainWindow;     <---------

};

Window2.cpp:


#include "Window2.h"

void Window2::setup() {

	ofBackground(0);
	ofSetVerticalSync(false);
	secondString = "second window";
}

void Window2::update() {

}

void Window2::draw() {

	ofSetColor(255);
	stringstream ss;
	ss << "framerate: " << ofToString(ofGetFrameRate(), 0) << endl;
	ss << "secondString: " << secondString << endl;
	//ss << "mainString: " << mainWindow->mainString << endl;      <---------
	ofDrawBitmapString(ss.str().c_str(), 20, 20);

}

Hey @rgthings , I think you’re getting compiler errors because of a circular dependency. Window2 needs to have ofApp compiled before it can compile, since it has an ofApp thing in it. And ofApp needs to have Window2 compiled before it can compile, since it has a Window2 thing in it. There is kind of a nice discussion about it here:

I’m hopeful it will compile with adding some forward declarations, includes, and keeping the #pragma once statements:
Window2.h:

#pragma once // keep this so it just gets done once

#include "ofMain.h"
#include "ofApp.h" // include ofApp.h so it knows where to find class ofApp

class ofApp; // add a forward declaration

class Window2 : public ofBaseApp {
public:
    void setup();
    void update();
    void draw();
    string secondString;
    std::shared_ptr<ofApp> mainWindow;
};

ofApp.h:

#pragma once // keep this so it just gets done once

#include "ofMain.h"
#include "Window2.h" // include Window2.h so it knows where to find class Window2

class Window2; // add a forward declaration of Window2

class ofApp : public ofBaseApp{
    public:
        void setup();
        void update();
        void draw();
        string mainString;
        std::shared_ptr<Window2> secWindow;
};
2 Likes

many thanks TimChi. I added the code you recommended and it works. I also learned that I had to make sure that the line, “secondApp->mainWindow = mainApp;” in main.cpp was uncommented otherwise I would receive read access violations. Very much appreciate your time with my newbie questions.

1 Like

Yes glad it worked! I had a forward declaration issue a few years ago but had forgotten all about that. So it was a fun refresher for me. The code you posted was fantastic and very helpful. It was simple to read and it compiled, and so easy to use and fiddle around with.

The read access error arises from trying to dereference a nullptr value (I think). Part of learning c++ is learning about different compiler errors, what they mean, and where to go looking to fix them. A std::shared_ptr<> has a value of nullptr unless it’s initialized with something.

1 Like