Forum: PC-Programmierung C++ Aufruf einer Funktion


von A.Wallner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe bisher nur in C Programmiert und bin etwas überfordert mit dem 
Aufrufen einer Funktion.
Ich verwende das Programm XMRIG und möchte den Miner pausieren wenn ich 
ein anderes Aufwendiges Programm auf dem Computer starte. Ich lade die 
Datei in der ich die Änderungen gemacht habe mal hoch.

In der Funktion xmrig::Miner::Miner(Controller *controller) erstelle ich 
einen Thread mit std::thread testx(Miner t1); welcher die Funktion t1() 
aufruft, dass funktioniert auch soweit.
Aus dieser Funktion möchte ich nun die Funktion 
xmrig::Miner::isRunningX("Programm"); aufrufen. Um dann zu entscheiden 
ob die Funktion setEnabled() mit false oder true aufgerufen wird. Bei 
diesen Aufrufen bekomme ich aktuell die Fehlermeldung "Bezeichner wurde 
nicht gefunden." Google nun schon länger aber ich bin nicht drauf 
gekommen warum ich die Funktion nicht aufrufen kann. Habe auch mehrere 
Möglichkeiten probiert aber ohne Erfolg. Ich hoffe ihr könnt mir helfen. 
Folgend die zwei Funktionen.


1
void t1()
2
{
3
    //using namespace xmrig;
4
    int status = 0;
5
    while (1)
6
    {
7
        Sleep(500);
8
        if ((isRunning("Unbennant - Editor")) || (isRunning("notepad")));// { Miner setEnabled(false); }
9
    }
10
}
11
12
13
bool xmrig::Miner::isRunningX(LPCSTR test)
14
{
15
    HWND hwnd;
16
    hwnd = FindWindowA(NULL, test);
17
    if (hwnd != 0) {
18
        return true;
19
    }
20
    else {
21
        return false;
22
    }
23
}

mfg
Awallner

von A.Wallner (Gast)


Lesenswert?

Korrektur:
Ich habe im obigen Beispiel das X in isRunning vergessen, dass ist im 
Programm natürlich nicht so.

von Dirk K. (merciless)


Lesenswert?

Poste mal die genaue Fehlermeldung. Ich vermute,
die Funktion isRunningX() wird nicht gefunden,
weil du den Namespace weggelassen hast und der
aufrufende Code in einem anderen Namespace liegt.

merciless

von Zombie (Gast)


Lesenswert?

xmrig::Miner ist eine Klasse. In diese kannst du nicht einfach eine 
Funktion hinzufügen. Zumal sie dort auch thematisch gar nicht hingehört.

Warum machst du nicht einfach eine normale Funktion wie in C auch?

von A.Wallner (Gast)


Angehängte Dateien:

Lesenswert?

Dirk K. schrieb:
> Poste mal die genaue Fehlermeldung. Ich vermute,
> die Funktion isRunningX() wird nicht gefunden,
> weil du den Namespace weggelassen hast und der
> aufrufende Code in einem anderen Namespace liegt.

Hab ich angehängt. Dass stimmt, wie aber erreiche ich einen gleichen 
Namensbereich? Versuche ich die Funktion mit 
xmrig::Miner::isRunningX(..) aufzurufen kommt: Unzulässiger Aufruf einer 
nicht statischen Memberfunktion. Allerdings konnte ich diesen Fehler 
auch nicht umgehen..

Zombie schrieb:
> Warum machst du nicht einfach eine normale Funktion wie in C auch?

Das hatte ich zuerst, was auch dann soweit funktioniert. Allerdings bin 
ich auf die Funktion xmrig::Miner::setEnable angewiesen und somit habe 
ich wieder das gleiche Problem wie vorhin..

mfg
Awallner

von Zombie (Gast)


Lesenswert?

A.Wallner schrieb:
> Allerdings bin
> ich auf die Funktion xmrig::Miner::setEnable angewiesen und somit habe
> ich wieder das gleiche Problem wie vorhin..

Du brauchst dafür natürlich die Instanz auf die diese Member Funktion 
ausgeführt werden soll. Also entweder die Instanz als Referenz (oder 
meinetwegen als Pointer) an t1 übergeben, oder xmrig::Miner als globale 
Variable instanzieren (was - denke ich - in diesem Fall völlig legitim 
wäre. Es werden wohl kaum mehrere Instanzen dieser Klasse in einem 
Programm gebraucht).

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

A.Wallner schrieb:
> Das hatte ich zuerst, was auch dann soweit funktioniert. Allerdings bin
> ich auf die Funktion xmrig::Miner::setEnable angewiesen und somit habe
> ich wieder das gleiche Problem wie vorhin..
1
Miner *m = new Miner();
2
x->isRunningX();
3
x->setEnabled();
4
...
5
delete m;

von A.Wallner (Gast)


Angehängte Dateien:

Lesenswert?

Zombie schrieb:
> Du brauchst dafür natürlich die Instanz auf die diese Member Funktion
> ausgeführt werden soll. Also entweder die Instanz als Referenz (oder
> meinetwegen als Pointer) an t1 übergeben, oder xmrig::Miner als globale
> Variable instanzieren (was - denke ich - in diesem Fall völlig legitim
> wäre. Es werden wohl kaum mehrere Instanzen dieser Klasse in einem
> Programm gebraucht).

Wie mache ich das am Besten? Reicht es wenn ich z.B. aus der Funktion t1 
dann einfach eine integer Variable Rückgebe? Oder wie kann ich 
xmrig::Miner Global instanzieren?

@Irgend W. (Firma: egal) (irgendwer)
Angehängte Meldung erscheint wenn ich es wie Folgt mache:
1
xmrig::Miner::Miner(Controller *controller)
2
    : d_ptr(new MinerPrivate(controller))
3
{
4
    const int priority = controller->config()->cpu().priority();
5
    if (priority >= 0) {
6
        Platform::setProcessPriority(priority);
7
        Platform::setThreadPriority(std::min(priority + 1, 5));
8
    }
9
10
//Habe die ifdef entfernt für die Übersicht
11
12
    //xx Changes
13
    //std::thread testx(Miner t1);
14
    Miner* m = new Miner();
15
    x->t1(); //Bei verwendung von m statt x erscheint trotzdem die Meldung das die funktion gelöscht ist
16
    delete m;
17
18
}

von A.Wallner (Gast)


Lesenswert?

Hab mal nen anderen Weg versucht und t1 auf void xmrig::Miner::t1(void) 
unbenannt. Mit der Erstellung des Threads std::thread testx(&Miner::t1, 
this); bekomme ich beim Übersetzen keine Fehlermeldung. Beim Starten 
bricht das Programm allerdings ab und beendet sich.

von Sheeva P. (sheevaplug)


Lesenswert?

A.Wallner schrieb:
> Ich verwende das Programm XMRIG und möchte den Miner pausieren wenn ich
> ein anderes Aufwendiges Programm auf dem Computer starte.

Bitte entschuldige, aber wenn ich mir Deinen Anwendungsfall so durchlese 
und darüber nachdenke, beschleichen mich gewisse Zweifel, ob das, was Du 
vorhast, wirklich so eine gute Idee ist. Leider kenne ich mich mit 
Windows und Deiner Entwicklungsumgebung ebensowenig aus wie mit dem 
Programm, das Du da benutzen möchtest. Insofern kann es sein, daß ich 
totalen Unsinn schreibe, dann sei so freundlich, meinen Beitrag bitte 
einfach zu ignorieren.

Zunächst ist mir in Deinen Ausführungen ein grundsätzliches 
Verständnisproblem aufgefallen, denn was Du aufzurufen versuchst, ist 
keine Funktion, sondern eine Methode. Eine Methode unterscheidet sich 
insofern von einer Funktion, als eine Methode an eine Datenstruktur -- 
eine Klasse -- gebunden ist, oder genauer: zur Laufzeit an eine Instanz 
einer Klasse. Im Gegensatz zu einer Funktion wird einer Methode als 
versteckter Parameter ein Zeiger auf die konkrete Instanz mitgegeben -- 
in C++ als versteckter Zeiger namens "this". Deswegen geht das hier, 
obwohl "this" gar nicht deklariert wird:

[c]
#include <iostream>

class Ding {
public:
    Ding(void) {
  this->eins = 1;
    }
    void out(void) {
  std::cout << "Ding.eins = " << this->eins << std::endl;
    }
private: int eins;
};

int main(void) {
    Ding d{};
    d.out();
    return 0;
}
[/code]

Außerdem ist mir aufgefallen, daß Du das Programm XMRIG sogar selbst 
verändert zu haben scheinst, um die gewünschte Funktionalität (nicht 
Funktionen, wohlgemerkt) hinzuzufügen. Natürlich, das kann man machen, 
aber sowas erscheint mir in einer objektorientierten Sprache wie C++ ein 
bisschen... merkwürdig. Du könntest doch einfach von der Miner-Klasse 
erben und dann ganz einfach Deiner geerbten Klasse die gewünschte 
Funktionalität hinzufügen? Das hätte auch den Vorteil, daß Du die Basis 
lediglich mit "git pull" aktualisieren, die gesamte Software 
neuübersetzen und -installieren mußt, ohne an der Basis etwas patchen zu 
müssen.

Aber gut, das waren bisher nur Details, denn tatsächlich würde ich an 
Deiner Stelle schon grundsätzlich in eine ganz andere Richtung denken. 
Nämlich viel grundsätzlicher: was für ein Programm läuft eigentlich, 
wenn es gerade keine Benutzerinteraktion gibt? Genau: ein 
Bildschirmschoner... und so gibt es nun bereits eine Reihe von 
"Rechenprogrammen" wie zum Beispiel Seti@Home, die es haargenau so 
machen.

Ob das unter Windows mit C++ geht und wie es möglich ist, weiß ich 
nicht, da ich mich damit, wie gesagt, nicht auskenne. Unter einem 
UNIXoiden wie Linux würd ich mir dazu allerdings einen kleinen 
Python-"Bildschirmschoner" mittels den Modulen "subprocess" (ein 
Builtin) und "psutil" (ein externes Modul) bauen, und es als 
Bildschirmschoner einrichten, das etwa Folgendes macht:
1
Wenn ich beendet werde:
2
    schicke "XRMPP" schlafen
3
Wenn "XRMPP" nicht läuft:
4
    starte "XRMPP" im Hintergrund
5
Ansonsten:
6
    wecke "XRMPP" auf

Auf diese Weise kannst Du die Features Deines Betriebssystems benutzen 
(und im Zweifelsfall sogar mit dem Bildschirmschoner Statistiken oä. 
darstellen), ohne irgendetwas an XRMPP verändern zu müssen.

Wie gesagt, ich kenne mich mit Windows und dem ganzen Gerümpel nicht 
aus, aber vielleicht ist das ein eleganterer Weg. Bestimmt geht da auch 
etwas mit dieser Powershell, Win-C++, Win-C# oder Visual Basic...

HTH, YMMV. ;-)

von MaWin (Gast)


Lesenswert?

1
#include <iostream>
2
3
using namespace std;
4
5
class CMiner
6
{
7
    public:
8
        bool isRunning (string textStr, bool returnValue) { return(returnValue); };
9
};
10
11
void ti (void)
12
{
13
    CMiner localMiner;
14
    while (1)
15
    {
16
        if (localMiner.isRunning("Unbennant - Editor", true) || localMiner.isRunning("notepad", false))
17
            break;// { Miner setEnabled(false); }
18
    }
19
}
20
21
int main()
22
{
23
    cout << "start!" << endl;
24
    ti();
25
    cout << "finished!" << endl;
26
    return 0;
27
}

von Jörg (Gast)


Lesenswert?


Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.