🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.iso-c++
3 messages
3 total messages Started by =?UTF-8?Q?Heinz- Thu, 22 Jun 2017 16:05
Multiple Definition / Extern und "gehaltene" Varible
#52638
Author: =?UTF-8?Q?Heinz-
Date: Thu, 22 Jun 2017 16:05
177 lines
4386 bytes
Hallo,

ich habe hier ein Projekt das darauf basiert, das eine Variable einer
Bibliothek die einem Programm in Main aufgerufen wurde gehalten wird bis
der Ablauf innerhalb der Bibliothek beendet ist.

(Ich versuche zur Erklärung den Kern zu treffen, da es sonst einfach
viel zu lang werden würde.)

Ein Programm (IDABase) sieht in groben Zügen so aus:

hSections.h:
class c_IDABase{
public:

	class cSecBase{
	public:
		class c_Areas{
		public:
			XIDAButton *BtnIDA;
			XIDA_Button_Event Ev_BtnIDA;
			XIDAButton *BtnTasks[10];
			XIDA_Button_Event Ev_BtnTasks;
		};
		c_Areas Areas;
		IDASection *Section;
		XIDA_EventMask Events;
	};
	IDA *mIDA = NULL;
	XIDA *mXIDA = NULL;
	c_IDABase mIDA_Base;

inline void Quit(){
	mIDA_Base.SecBase.Areas.BtnIDA = NULL;
	for(int i = 0; i < 10; i++)
		mIDA_Base.SecBase.Areas.BtnTasks[i] = NULL;
	mIDA_Base.SecBase.Section = NULL;
	mXIDA =NULL;
	mIDA =NULL;
}

--------------------------------------------------------------

SecBase.cpp:
#include "hsections.h"
#include "secbase_ev.cpp"

void SecBase_Init(){
	SecBase->Events.mEvent_Click = &SecBase_Click;
	SecBase->Section = mXIDA->RegisterSection("secBase", (int) Sec_Style_Simple
		, (int) StatBox_Full, 1);
	SecBase->Section->SetEventMask(&SecBase->Events);
}

--------------------------------------------------------------

main:
#include "hsections.h"
#include "secbase.cpp"

int main(int argc, char *argv[]){
	IDA nIDA(mIdentFrom.c_str(), mIdent.c_str());
	mIDA = &nIDA;
	mXIDA = mIDA->_XIDA();
	c_IDABase nIDABase;
	mIDA_Base = nIDABase;
};

In der kompletten Version läuft das auch, absolut fehlerfrei und lt.
Valgrind ohne Leaks.

Die Bibliothek, die quasi gehalten werden soll ist also IDA. main wird
also beendet, aber IDA läuft dann weiter, bis alle Fenster für dieses
Programm geschlossen wurden...

Jetzt zu den Problemen...
1) Multiple Definition

Die selbe Architektur (und ich habe es zich mal gegengecheckt) läuft in
einem anderen Programm (IDABrowse) nicht.
Mit der selben Architektur kommt der Fehler Multiple Definition, an zich
Stellen (u.a. mXIDA, mIDA) .
Die Frage, die sich mir stellt ist: Warum?
Warum klappt es bei IDABase, und warum nicht mehr in IDABrowse?
Einzig habe ich z. Teil andere Namen für Variablen. Ich habe aber schon
_alle_ Namen geändert. Obwohl beide in einem eigenen Prozess laufen,
könnte es ja sein...

2) Extern
Um weiter zu kommen habe ich mich dann mal in Extern eingelesen...

hGlobal.h:
#include <ida.h>
#include <xida.h>

class c_Sections{
	... // Also eine Klasse wie oben
}

extern IDA *mIDA;
extern XIDA *mXIDA;

extern c_Sections *mSections;
extern c_Sections::cSecBrowse *SecBrowse;
extern c_Sections::cSecConf *SecConf;

extern void AppQuit();
extern int IsQuit;

--------------------------------------------------------------

XIDAInit.cpp:
#include "hglobal.h"

IDA *mIDA = NULL;
XIDA *mXIDA = NULL;

int IsQuit = 0;

void AppQuit(){
	mXIDA = NULL;
	mIDA = NULL;
	IsQuit = 1;
}

--------------------------------------------------------------

main:
#include "hglobal.h"
#include "secbrowse.cpp"
#include <unistd.h>

using namespace std;

int main(int argc, char *argv[]){
	if(argc < 3){return 1;}
	std::string mIdent, mIdentFrom;
	mIdentFrom = (std::string) argv[1];
	mIdent = (std::string) argv[2];
	IDA nIDA(mIdentFrom.c_str(), mIdent.c_str());
	c_Sections nSections;
	mIDA = &nIDA;
	mXIDA = mIDA->_XIDA();
	mSections = &nSections;

	SecBrowse = &nSections.SecBrowse;
	SecConf = &nSections.SecConf;

	SecBrowse_Init();
	mXIDA->Load(SecBrowse->Section);
	SecBrowse->Section->Show(1);
	while(IsQuit == 0){
		usleep(15000);
	}
	return 0;
}

Auch das läuft _so_ einwandfrei.
Aber mich stört dieser Loop am Ende von main...
Aber wenn ich diesen weglasse, dann wird diese Instanz von IDA sofort
nach Rückgabe von main beendet.

Ich hoffe, man erkennt den Zusammenhang zwischen dem obigen und diesem.
In main wird IDA instanziiert und wird/soll im Speicher gehalten
(werden), bis eben IDA beendet ist, auch über die Rückgabe von main
hinaus...

Wo ist denn da jetzt der Unterschied zwischen
IDA *mIDA; // vom obigen Teil, wo ja mIDA gehalten wird
und
Extern IDA *mIDA; // wo mIDA nicht gehalten wird

Eine zusätzliche Frage ist:
Was könnte ich denn an der Architektur ändern, das IDA *mIDA (extern,
oder nicht) im Speicher gehalten wird _und_ keine Multiple
Definition-Errors erzeugt?

Heinz-Mario Frühbeis
Re: Multiple Definition / Extern und "gehaltene" Varible
#52639
Author: =?UTF-8?Q?Heinz-
Date: Fri, 23 Jun 2017 11:03
49 lines
1444 bytes
Am 22.06.2017 um 16:05 schrieb Heinz-Mario Frühbeis:
>
[...]
>

Ich habe mich mal dran gesetzt um herauszufinden, wie es denn mit dem
Prozess so "aussieht".

Das ist ein Teil der Abfrage, wenn IDA beendet/dekonstuktet wird...

				nPID = wait(&status);
				if ( WIFEXITED(status) ) {
					cout << "TEST STATUS 1 -- " << status << " -- " <<
WIFEXITED(status) << endl;
				} else if (WIFSIGNALED(status)) {
					cout << "TEST STATUS 2 -- " << status << " -- " << WTERMSIG(status)
<< endl;
				} else if (WIFSTOPPED(status)) {
					cout << "TEST STATUS 3 -- " << status << " -- " << WSTOPSIG(status)
<< endl;
				} else {
					cout << "TEST STATUS 4 -- " << status << " -- " <<
WIFEXITED(status) << endl;
				}

Das ist die Ausgabe, wenn der Loop _nicht_ gesetzt ist:
TEST STATUS 2 -- 11 -- 11
(Allerdings ploppt das Fenster _ganz_ _kurz_ auf und dann ist "Ende im
Schacht".)

Und das, wenn der Loop vorhanden ist:
TEST STATUS 2 -- 11 -- 11

Es sieht also so aus, daß wenn ich extern-Variablen nutze der Prozess
einfach beendet wird...
Aber warum?
Ich weiß langsam aber sicher nicht mehr weiter, wo ich noch suchen könnte.

Bei IDA:
IDA_A::~IDA_A(){
cout << "DEKONSTRUKT +++++++++++++++++++++ IDAA -- " << this->mIdent
<< " -- " << this->WaitForXIDA << " -- " << endl; // Die Ausgabe ist
"IDABrowse" -- 1
while ( this->WaitForXIDA == 1) {
}

}

// Hier kommt dann das Programm mit extern-Variablen und ohne Loop gar
nicht mehr an...
Re: [FYI] Extern und "gehaltene" Varible
#52640
Author: =?UTF-8?Q?Heinz-
Date: Fri, 23 Jun 2017 23:53
53 lines
1088 bytes
Am 23.06.2017 um 16:46 schrieb Heinz-Mario Frühbeis:
> Am 22.06.2017 um 16:05 schrieb Heinz-Mario Frühbeis:
[...]

Hallo,

gerade habe ich meiner XIDA-Bibliothek eine externe Variable aufgenommen...

Header:
#include "xida_a.h"

extern XIDA_A XIDA_Ex;

In XIDA.cpp:
#include "hxida_global.h"
#include "xida.h"

XIDA_A XIDA_Ex;

XIDA::XIDA(void* vPara, void* vPara1){
	XIDA_Ex.Init(vPara, vPara1);
}

Und in einer XIDA_Api.cpp:
#include "xida_api.h"
#include "hxida_global.h"

void Eine_Function_Die_XIDA_Ex_nutzt(){
	XIDA_Ex.Irgendwas();
}

Und mit diesem Konstrukt "rauscht" das Programm quasi wieder durch,
heißt XIDA_Ex wird _nicht_ im Speicher gehalten...

Warum ist das so? Und wie könnte man es erreichen, daß die externe
Variable gehalten wird?

Denn ohne externer Variable, ...

also in XIDA.cpp:
#include "xida.h"
#include "xida_a.h"

XIDA_A XIDA_Ex;

XIDA::XIDA(void* vPara, void* vPara1){
	XIDA_Ex.Init(vPara, vPara1);
}

wird XIDA_Ex im Speicher gehalten und das Programm wird erst beendet,
wenn der Dekonstruktor von XIDA beendet ist.

Mit Gruß
Heinz-Mario Frühbeis
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads