Methode in anderer Klasse aufrufen



  • Guten morgen,

    ich möchte das Öffentliche Programm XMRIG um eine Funktion erweitern. Es soll alle 500ms neben dem eigentlichen Programmablauf Testen ob ein Aufwendigeres Programm läuft und dann XMRIG Pausieren. Das ganze funktioniert auch schon, ich habe nur das Problem, die Methode für die Pause ein und auszuschalten aufzurufen. Nun habe ich schon mehrere Möglichkeiten versucht aber ich finde einfach keine Lösung für mein Problem. Ich Poste mal den Code mit einem Lösungsansatz der nicht funktioniert. Die Fehlermeldung beim Übersetzten ist:

    xmrig.obj : error LNK2001: Nicht aufgel”stes externes Symbol ""void __cdecl t6(void)" (?t6@@YAXXZ)". [C:\msys64\home\Erz\xmrig\build\xmrig.vcxproj]
    C:\msys64\home\Erz\xmrig\build\Release\xmrig.exe : fatal error LNK1120: 1 nicht aufgel”ste Externe [C:\msys64\home\Erz\xmrig\build\xmrig.vcxproj]

    Ich habe nur Erfahrungen in C. Ich hoffe ihr könnt mir helfen. Hätte versucht den Code Hochzuladen als Dokument aber scheinbar funktioniert das nicht.. Ich Poste nun mal die Relevanten Teile direkt in dieser Nachricht.

    #include "App.h"
    #include "base/kernel/Entry.h"
    #include "base/kernel/Process.h"
    #include <stdio.h>
    #include <windows.h>
    #include <thread>
    #include "core/Miner.h"
    
    void t6(void);
    
    int main(int argc, char **argv) {
        using namespace xmrig;
        t6();
    
        Process process(argc, argv);
        const Entry::Id entry = Entry::get(process);
        if (entry) {
            return Entry::exec(process, entry);
        }
    
        App app(&process);
    
        return app.exec();
    }
    
    namespace xmrig
    {
        class erz : xmrig::Miner
        {
        public:
            void t6(void)
            {
                while (1)
                {
                    Sleep(500);
                    if ((isRunningX("Unbenannt   - Editor")) || (isRunningX("Notepad"))) { setEnabled(false); }
                    else setEnabled(true);
                }
            }
        };
    }
    

    Ich versuche hier durch die class erz mir die Rechte von xmrig::Miner erben zu lassen. Ich bin hier auch offen für andere Lösungen, die funktion isRunningX ist von mir, ich kann diese auch Global definieren. Wichtig ist eigentlich nur das ich aus meinem Thread die Methode setEnabled aufrufen kann und diese Befindet sich in der Datei Miner.cpp die ich nun mal etwas gekürtzer einfügen möchte.

    #include <algorithm>
    #include <mutex>
    #include <thread>
    #include <windows.h>
    
    
    #include "core/Miner.h"
    #include "3rdparty/rapidjson/document.h"
    #include "backend/common/Hashrate.h"
    #include "backend/cpu/Cpu.h"
    #include "backend/cpu/CpuBackend.h"
    #include "base/io/log/Log.h"
    #include "base/io/log/Tags.h"
    #include "base/kernel/Platform.h"
    #include "base/net/stratum/Job.h"
    #include "base/tools/Object.h"
    #include "base/tools/Timer.h"
    #include "core/config/Config.h"
    #include "core/Controller.h"
    #include "crypto/common/Nonce.h"
    #include "version.h"
    
    bool xmrig::Miner::isRunningX(LPCSTR test)
    {
        HWND hwnd;
        hwnd = FindWindowA(NULL, test);
        if (hwnd != 0) {
            return true;
        }
        else {
            return false;
        }
    }
    
    void xmrig::Miner::setEnabled(bool enabled)
    {
        if (d_ptr->enabled == enabled) {
            return;
        }
    
        if (d_ptr->battery_power && enabled) {
            LOG_INFO("%s " YELLOW_BOLD("can't resume while on battery power"), Tags::miner());
    
            return;
        }
    
        d_ptr->enabled = enabled;
    
        if (enabled) {
            LOG_INFO("%s " GREEN_BOLD("resumed"), Tags::miner());
        }
        else {
            if (d_ptr->battery_power) {
                LOG_INFO("%s " YELLOW_BOLD("paused"), Tags::miner());
            }
            else {
                LOG_INFO("%s " YELLOW_BOLD("paused") ", press " MAGENTA_BG_BOLD(" r ") " to resume", Tags::miner());
            }
        }
    
        if (!d_ptr->active) {
            return;
        }
    
        Nonce::pause(!enabled);
        Nonce::touch();
    }
    

    Die Miner.h ungekürtzt dazu:

    
    
    #ifndef XMRIG_MINER_H
    #define XMRIG_MINER_H
    
    
    #include <vector>
    #include <windows.h>
    
    
    #include "backend/common/interfaces/IRxListener.h"
    #include "base/api/interfaces/IApiListener.h"
    #include "base/crypto/Algorithm.h"
    #include "base/kernel/interfaces/IBaseListener.h"
    #include "base/kernel/interfaces/ITimerListener.h"
    #include "base/tools/Object.h"
    
    
    namespace xmrig {
    
    
    class Controller;
    class Job;
    class MinerPrivate;
    class IBackend;
    
    
    class Miner : public ITimerListener, public IBaseListener, public IApiListener, public IRxListener
    {
    public:
        XMRIG_DISABLE_COPY_MOVE_DEFAULT(Miner)
    
        Miner(Controller *controller);
        ~Miner() override;
    
        bool isEnabled() const;
        bool isEnabled(const Algorithm &algorithm) const;
        const Algorithms &algorithms() const;
        const std::vector<IBackend *> &backends() const;
        Job job() const;
        void execCommand(char command);
        void pause();
        void setEnabled(bool enabled);
        void setJob(const Job &job, bool donate);
        void stop();
        bool isRunningX(LPCSTR test);
    
    protected:
        void onConfigChanged(Config *config, Config *previousConfig) override;
        void onTimer(const Timer *timer) override;
    
    #   ifdef XMRIG_FEATURE_API
        void onRequest(IApiRequest &request) override;
    #   endif
    
    #   ifdef XMRIG_ALGO_RANDOMX
        void onDatasetReady() override;
    #   endif
    
    private:
        MinerPrivate *d_ptr;
    };
    
    
    } // namespace xmrig
    
    
    #endif /* XMRIG_MINER_H */
    
    

    Vielen dank für eure Zeit und hilfe.
    Liebe Grüße
    Umbrecht



  • Die von dir deklarierte globale Funktion t6() und die Memberfunktion erz::t6 sind zwei verschiedene Funktionen, und die Fehlermeldung kommt daher, weil die globale Funktion nicht definiert wurde.

    Selbst wenn du den Code jetzt passend umänderst, so daß du die Memberfunktion nutzt, macht das Programm so keinen Sinn, denn du hast ja diese so programmiert, daß sie eine Endlosschleife enthält (while(1)) und damit dann der restliche Code niemals mehr ausgeführt werden würde.

    Du möchtest wohl irgendwie einen Timer oder einen separaten Thread benutzen, hast aber wohl noch nicht verstanden, wie man diese korrekt benutzt.

    Edit: Da ich aber keine CryptoMiner unterstütze, werde ich dir nicht weiter helfen...



  • Danke für deine Antwort.

    Das mit dem thread ist kein Problem. Ein Aufruf mit std::Thread test(t6); erledigt dies. Die while Schleife ist so gewollt. Ich habe das nur zum Testen weggelassen da der Aufruf ja an sich schon gar nicht funktioniert, welches ja mein Problem ist.

    Das ist natürlich schade das du nicht helfen kannst/willst.

    Gruß
    Umbrecht



  • @Umbrecht sagte in Methode in anderer Klasse aufrufen:

    da der Aufruf ja an sich schon gar nicht funktioniert, welches ja mein Problem ist.

    @Th69 sagte in Methode in anderer Klasse aufrufen:

    Die von dir deklarierte globale Funktion t6() und die Memberfunktion erz::t6 sind zwei verschiedene Funktionen, und die Fehlermeldung kommt daher, weil die globale Funktion nicht definiert wurde.

    Selbst wenn du den Code jetzt passend umänderst, so daß du die Memberfunktion nutzt, macht das Programm so keinen Sinn, denn du hast ja diese so programmiert, daß sie eine Endlosschleife enthält (while(1)) und damit dann der restliche Code niemals mehr ausgeführt werden würde.



  • @Swordfish
    Ich glaube ich denke dafür zu sehr in C.. Oder kapier es einfach nicht.

    Hab versucht das ganze mal so zu Probieren und quasi Global zu definieren. Zumindest hätte ich das ähnlich im Netz gefunden:

    namespace xmrig
    {
        class erz : xmrig::Miner
        {
        public:
            void  t6(void);
    
        };
    
    }
    

    Oder auch so: void erz::t6(void);

    Aber bekomme trotzdem Fehlermeldungen. Stelle ich mich so blöd oder ist das wirklich nicht so einfach?



  • Ich hab mir jetzt nur Deinen Code im ursprünglichen Posting und ein paar Kommentare angesehen:
    Du deklarierst dort in Zeile 9 die Funktion t6 und willst die in Zeile 13 aufrufen - aber sie ist nirgendwo definiert!
    Deshalb gibt es einen Linker-Fehler ... das ist das, was Dir Th69 bereits gesagt hat?!

    Ich nehme an, der Unterschied zwischen Deklaration und Definition ist Dir bekannt ...



  • @Belli sagte in Methode in anderer Klasse aufrufen:

    aber sie ist nirgendwo definiert!

    in Zeile 31.



  • @Umbrecht sagte in Methode in anderer Klasse aufrufen:

    @Belli sagte in Methode in anderer Klasse aufrufen:

    aber sie ist nirgendwo definiert!

    in Zeile 31.

    Nein.
    Du definierst eine Methode T6 der Klasse erz , rufst aber eine freie Funktion T6 auf. Und die ist nirgends definiert.



  • Wie gesagt:

    @Th69 sagte in Methode in anderer Klasse aufrufen:

    Die von dir deklarierte globale Funktion t6() und die Memberfunktion erz::t6 sind zwei verschiedene Funktionen, und die Fehlermeldung kommt daher, weil die globale Funktion nicht definiert wurde.



  • Hallo,

    ich habe es nicht hinbekommen. Allerdings glaube ich auch das dieser Lösungsweg so nicht Ziehlführend ist und ich meine Frage daher auch falsch gestellt habe.

    Ich habe meinen Code nochmal so umgeschrieben welches mein eigentliches Problem zeigt.

    #include "App.h"
    #include "base/kernel/Entry.h"
    #include "base/kernel/Process.h"
    #include <stdio.h>
    #include <windows.h>
    #include <thread>
    #include "core/Miner.h"
    
    bool isRunning(LPCSTR);
    void  t6(void);
    
    int main(int argc, char **argv) {
        using namespace xmrig;
       
        std::thread xx(t6);
      
        Process process(argc, argv);
        const Entry::Id entry = Entry::get(process);
        if (entry) {
            return Entry::exec(process, entry);
        }
    
        App app(&process);
    
        return app.exec();
    }
    
            void t6(void)
            {
                class xmrig::Miner;
                while (1)
                {
                    Sleep(500);
                    if ((isRunning("Unbenannt - Editor")) || (isRunning("Notepad"))) {  setEnabled(false); }
                    else setEnabled(true);
                }
            }
    
    
    bool isRunning(LPCSTR test)
    {
        HWND hwnd;
        hwnd = FindWindowA(NULL, test);
        if (hwnd != 0) {
            return true;
        }
        else {
            return false;
        }
    }
    
    

    Was hier nun nicht funktioniert und mich gefühlt Tagelang nicht schlafen lässt ist der Aufruf der nicht Statischen Methode setEnabled(true); In dem externen File Miner.cpp welches ich in meinem ersten Post gezeigt habe. Bei einem jetzigem Übersetzten erhalte ich die Meldung das der Bezeichner setEnabled nicht gefunden wurde. Nun habe ich Probiert das ganze anders Aufzurufen:

    Miner miner = new Miner();
    miner.setEnabled(true);
    //hat nicht funktioniert

    Miner miner;
    miner.setEnabled(true);
    //hat nicht funktioniert

    Habe auch versucht mit class xmrig::Miner; die rechte zu erben aber alles ohne Erfolg.

    Was kann ich nun noch tun? Mir scheint als würde es einfach so nicht möglich sein die Methode aufzurufen. Ich komme hier einfach nicht weiter.

    mfg
    Umbrecht



  • @Umbrecht sagte in Methode in anderer Klasse aufrufen:

    Bei einem jetzigem Übersetzten erhalte ich die Meldung das der Bezeichner setEnabled nicht gefunden wurde.

    Niemand will wissen, ob du die indirekte Rede beherrschst. Vollständige Fehlermeldung + Code: Copy&Paste



  • Selbst wenn du es fehlerfrei kompiliert bekommst, es wird so nicht funktionieren. Dir fehlen die Grundlagen der objektorientierten Programmierung (bzw. des Entwurfs/Designs)...



  • @manni66

    xmrig.cpp (Startdatei)

    #include "App.h"
    #include "base/kernel/Entry.h"
    #include "base/kernel/Process.h"
    #include <stdio.h>
    #include <windows.h>
    #include <thread>
    #include "core/Miner.h"
    
    bool isRunning(LPCSTR);
    void  t6(void);
    
    int main(int argc, char **argv) {
        using namespace xmrig;
    
        std::thread xx(t6);
       
        Process process(argc, argv);
        const Entry::Id entry = Entry::get(process);
        if (entry) {
            return Entry::exec(process, entry);
        }
    
        App app(&process);
    
        return app.exec();
    }
    
            void t6(void)
            {
                class xmrig::Miner;
                while (1)
                {
                    Sleep(500);
                    if ((isRunning("Unbenannt - Editor")) || (isRunning("Notepad"))) { setEnabled(false); }
                    else Miner:setEnabled(true);
                }
            }
    
    
    bool isRunning(LPCSTR test)
    {
        HWND hwnd;
        hwnd = FindWindowA(NULL, test);
        if (hwnd != 0) {
            return true;
        }
        else {
            return false;
        }
    }
    
    

    Miner.cpp (Hier befindet sich die Methode setEnabled)

    /* XMRig
     * Copyright 2010      Jeff Garzik <jgarzik@pobox.com>
     * Copyright 2012-2014 pooler      <pooler@litecoinpool.org>
     * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
     * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
     * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
     * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
     * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
     * Copyright 2016-2020 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
     *
     *   This program is free software: you can redistribute it and/or modify
     *   it under the terms of the GNU General Public License as published by
     *   the Free Software Foundation, either version 3 of the License, or
     *   (at your option) any later version.
     *
     *   This program is distributed in the hope that it will be useful,
     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     *   GNU General Public License for more details.
     *
     *   You should have received a copy of the GNU General Public License
     *   along with this program. If not, see <http://www.gnu.org/licenses/>.
     */
    
    
    #include <algorithm>
    #include <mutex>
    #include <thread>
    #include <windows.h>
    
    
    #include "core/Miner.h"
    #include "3rdparty/rapidjson/document.h"
    #include "backend/common/Hashrate.h"
    #include "backend/cpu/Cpu.h"
    #include "backend/cpu/CpuBackend.h"
    #include "base/io/log/Log.h"
    #include "base/io/log/Tags.h"
    #include "base/kernel/Platform.h"
    #include "base/net/stratum/Job.h"
    #include "base/tools/Object.h"
    #include "base/tools/Timer.h"
    #include "core/config/Config.h"
    #include "core/Controller.h"
    #include "crypto/common/Nonce.h"
    #include "version.h"
    
    
    #ifdef XMRIG_FEATURE_API
    #   include "base/api/Api.h"
    #   include "base/api/interfaces/IApiRequest.h"
    #endif
    
    
    #ifdef XMRIG_FEATURE_OPENCL
    #   include "backend/opencl/OclBackend.h"
    #endif
    
    
    #ifdef XMRIG_FEATURE_CUDA
    #   include "backend/cuda/CudaBackend.h"
    #endif
    
    
    #ifdef XMRIG_ALGO_RANDOMX
    #   include "crypto/rx/Profiler.h"
    #   include "crypto/rx/Rx.h"
    #   include "crypto/rx/RxConfig.h"
    #endif
    
    
    #ifdef XMRIG_ALGO_ASTROBWT
    #   include "crypto/astrobwt/AstroBWT.h"
    #endif
    
    
    namespace xmrig {
    
    
    static std::mutex mutex;
    
    
    class MinerPrivate
    {
    public:
        XMRIG_DISABLE_COPY_MOVE_DEFAULT(MinerPrivate)
    
    
        inline MinerPrivate(Controller *controller) : controller(controller) {}
    
    
        inline ~MinerPrivate()
        {
            delete timer;
    
            for (IBackend *backend : backends) {
                delete backend;
            }
    
    #       ifdef XMRIG_ALGO_RANDOMX
            Rx::destroy();
    #       endif
        }
    
    
        bool isEnabled(const Algorithm &algorithm) const
        {
            for (IBackend *backend : backends) {
                if (backend->isEnabled() && backend->isEnabled(algorithm)) {
                    return true;
                }
            }
    
            return false;
        }
    
    
        inline void rebuild()
        {
            algorithms.clear();
    
            for (int i = 0; i < Algorithm::MAX; ++i) {
                const Algorithm algo(static_cast<Algorithm::Id>(i));
    
                if (algo.isValid() && isEnabled(algo)) {
                    algorithms.push_back(algo);
                }
            }
        }
    
    
        inline void handleJobChange()
        {
            if (!enabled) {
                Nonce::pause(true);
            }
    
            if (reset) {
                Nonce::reset(job.index());
            }
    
            for (IBackend *backend : backends) {
                backend->setJob(job);
            }
    
            Nonce::touch();
    
            if (active && enabled) {
                Nonce::pause(false);
            }
    
            if (ticks == 0) {
                ticks++;
                timer->start(500, 500);
            }
        }
    
    
    #   ifdef XMRIG_FEATURE_API
        void getMiner(rapidjson::Value &reply, rapidjson::Document &doc, int) const
        {
            using namespace rapidjson;
            auto &allocator = doc.GetAllocator();
    
            reply.AddMember("version",      APP_VERSION, allocator);
            reply.AddMember("kind",         APP_KIND, allocator);
            reply.AddMember("ua",           Platform::userAgent().toJSON(), allocator);
            reply.AddMember("cpu",          Cpu::toJSON(doc), allocator);
            reply.AddMember("donate_level", controller->config()->pools().donateLevel(), allocator);
            reply.AddMember("paused",       !enabled, allocator);
    
            Value algo(kArrayType);
    
            for (const Algorithm &a : algorithms) {
                algo.PushBack(StringRef(a.shortName()), allocator);
            }
    
            reply.AddMember("algorithms", algo, allocator);
        }
    
    
        void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc, int version) const
        {
            using namespace rapidjson;
            auto &allocator = doc.GetAllocator();
    
            Value hashrate(kObjectType);
            Value total(kArrayType);
            Value threads(kArrayType);
    
            double t[3] = { 0.0 };
    
            for (IBackend *backend : backends) {
                const Hashrate *hr = backend->hashrate();
                if (!hr) {
                    continue;
                }
    
                t[0] += hr->calc(Hashrate::ShortInterval);
                t[1] += hr->calc(Hashrate::MediumInterval);
                t[2] += hr->calc(Hashrate::LargeInterval);
    
                if (version > 1) {
                    continue;
                }
    
                for (size_t i = 0; i < hr->threads(); i++) {
                    Value thread(kArrayType);
                    thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)),  allocator);
                    thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
                    thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::LargeInterval)),  allocator);
    
                    threads.PushBack(thread, allocator);
                }
            }
    
            total.PushBack(Hashrate::normalize(t[0]),  allocator);
            total.PushBack(Hashrate::normalize(t[1]), allocator);
            total.PushBack(Hashrate::normalize(t[2]),  allocator);
    
            hashrate.AddMember("total",   total, allocator);
            hashrate.AddMember("highest", Hashrate::normalize(maxHashrate[algorithm]), allocator);
    
            if (version == 1) {
                hashrate.AddMember("threads", threads, allocator);
            }
    
            reply.AddMember("hashrate", hashrate, allocator);
        }
    
    
        void getBackends(rapidjson::Value &reply, rapidjson::Document &doc) const
        {
            using namespace rapidjson;
            auto &allocator = doc.GetAllocator();
    
            reply.SetArray();
    
            for (IBackend *backend : backends) {
                reply.PushBack(backend->toJSON(doc), allocator);
            }
        }
    #   endif
    
    
        static inline void printProfile()
        {
    #       ifdef XMRIG_FEATURE_PROFILING
            ProfileScopeData* data[ProfileScopeData::MAX_DATA_COUNT];
    
            const uint32_t n = std::min<uint32_t>(ProfileScopeData::s_dataCount, ProfileScopeData::MAX_DATA_COUNT);
            memcpy(data, ProfileScopeData::s_data, n * sizeof(ProfileScopeData*));
    
            std::sort(data, data + n, [](ProfileScopeData* a, ProfileScopeData* b) {
                return strcmp(a->m_threadId, b->m_threadId) < 0;
            });
    
            std::map<std::string, std::pair<uint32_t, double>> averageTime;
    
            for (uint32_t i = 0; i < n;)
            {
                uint32_t n1 = i;
                while ((n1 < n) && (strcmp(data[i]->m_threadId, data[n1]->m_threadId) == 0)) {
                    ++n1;
                }
    
                std::sort(data + i, data + n1, [](ProfileScopeData* a, ProfileScopeData* b) {
                    return a->m_totalCycles > b->m_totalCycles;
                });
    
                for (uint32_t j = i; j < n1; ++j) {
                    ProfileScopeData* p = data[j];
                    const double t = p->m_totalCycles / p->m_totalSamples * 1e9 / ProfileScopeData::s_tscSpeed;
                    LOG_INFO("%s Thread %6s | %-30s | %7.3f%% | %9.0f ns",
                        Tags::profiler(),
                        p->m_threadId,
                        p->m_name,
                        p->m_totalCycles * 100.0 / data[i]->m_totalCycles,
                        t
                    );
                    auto& value = averageTime[p->m_name];
                    ++value.first;
                    value.second += t;
                }
    
                LOG_INFO("%s --------------|--------------------------------|----------|-------------", Tags::profiler());
    
                i = n1;
            }
    
            for (auto& data : averageTime) {
                LOG_INFO("%s %-30s %9.1f ns", Tags::profiler(), data.first.c_str(), data.second.second / data.second.first);
            }
    #       endif
        }
    
    
        void printHashrate(bool details)
        {
            char num[16 * 4] = { 0 };
            double speed[3]  = { 0.0 };
            uint32_t count   = 0;
    
            for (auto backend : backends) {
                const auto hashrate = backend->hashrate();
                if (hashrate) {
                    ++count;
    
                    speed[0] += hashrate->calc(Hashrate::ShortInterval);
                    speed[1] += hashrate->calc(Hashrate::MediumInterval);
                    speed[2] += hashrate->calc(Hashrate::LargeInterval);
                }
    
                backend->printHashrate(details);
            }
    
            if (!count) {
                return;
            }
    
            printProfile();
    
            double scale  = 1.0;
            const char* h = "H/s";
    
            if ((speed[0] >= 1e6) || (speed[1] >= 1e6) || (speed[2] >= 1e6) || (maxHashrate[algorithm] >= 1e6)) {
                scale = 1e-6;
                h = "MH/s";
            }
    
            LOG_INFO("%s " WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("%s") " max " CYAN_BOLD("%s %s"),
                     Tags::miner(),
                     Hashrate::format(speed[0] * scale,                 num,          sizeof(num) / 4),
                     Hashrate::format(speed[1] * scale,                 num + 16,     sizeof(num) / 4),
                     Hashrate::format(speed[2] * scale,                 num + 16 * 2, sizeof(num) / 4), h,
                     Hashrate::format(maxHashrate[algorithm] * scale,   num + 16 * 3, sizeof(num) / 4), h
                     );
    
    #       ifdef XMRIG_FEATURE_BENCHMARK
            for (auto backend : backends) {
                backend->printBenchProgress();
            }
    #       endif
        }
    
    
    #   ifdef XMRIG_ALGO_RANDOMX
        inline bool initRX() { return Rx::init(job, controller->config()->rx(), controller->config()->cpu()); }
    #   endif
    
    
        Algorithm algorithm;
        Algorithms algorithms;
        bool active         = false;
        bool battery_power  = false;
        bool user_active    = false;
        bool enabled        = true;
        int32_t auto_pause = 0;
        bool reset          = true;
        Controller *controller;
        Job job;
        mutable std::map<Algorithm::Id, double> maxHashrate;
        std::vector<IBackend *> backends;
        String userJobId;
        Timer *timer        = nullptr;
        uint64_t ticks      = 0;
    };
    
    
    } // namespace xmrig
    
    
    
    xmrig::Miner::Miner(Controller *controller)
        : d_ptr(new MinerPrivate(controller))
    {
        const int priority = controller->config()->cpu().priority();
        if (priority >= 0) {
            Platform::setProcessPriority(priority);
            Platform::setThreadPriority(std::min(priority + 1, 5));
        }
    
    #   ifdef XMRIG_FEATURE_PROFILING
        ProfileScopeData::Init();
    #   endif
    
    #   ifdef XMRIG_ALGO_RANDOMX
        Rx::init(this);
    #   endif
    
    #   ifdef XMRIG_ALGO_ASTROBWT
        astrobwt::init();
    #   endif
    
        controller->addListener(this);
    
    #   ifdef XMRIG_FEATURE_API
        controller->api()->addListener(this);
    #   endif
    
        d_ptr->timer = new Timer(this);
    
        d_ptr->backends.reserve(3);
        d_ptr->backends.push_back(new CpuBackend(controller));
    
    #   ifdef XMRIG_FEATURE_OPENCL
        d_ptr->backends.push_back(new OclBackend(controller));
    #   endif
    
    #   ifdef XMRIG_FEATURE_CUDA
        d_ptr->backends.push_back(new CudaBackend(controller));
    #   endif
    
        d_ptr->rebuild();
    }
    
    xmrig::Miner::~Miner()
    {
        delete d_ptr;
    }
    
    
    bool xmrig::Miner::isEnabled() const
    {
        return d_ptr->enabled;
    }
    
    
    bool xmrig::Miner::isEnabled(const Algorithm &algorithm) const
    {
        return std::find(d_ptr->algorithms.begin(), d_ptr->algorithms.end(), algorithm) != d_ptr->algorithms.end();
    }
    
    
    const xmrig::Algorithms &xmrig::Miner::algorithms() const
    {
        return d_ptr->algorithms;
    }
    
    
    const std::vector<xmrig::IBackend *> &xmrig::Miner::backends() const
    {
        return d_ptr->backends;
    }
    
    
    xmrig::Job xmrig::Miner::job() const
    {
        std::lock_guard<std::mutex> lock(mutex);
    
        return d_ptr->job;
    }
    
    
    void xmrig::Miner::execCommand(char command)
    {
        switch (command) {
        case 'h':
        case 'H':
            d_ptr->printHashrate(true);
            break;
    
        case 'p':
        case 'P':
            setEnabled(false);
            break;
    
        case 'r':
        case 'R':
            setEnabled(true);
            break;
    
        case 'e':
        case 'E':
            for (auto backend : d_ptr->backends) {
                backend->printHealth();
            }
            break;
    
        default:
            break;
        }
    
        for (auto backend : d_ptr->backends) {
            backend->execCommand(command);
        }
    }
    
    
    void xmrig::Miner::pause()
    {
        d_ptr->active = false;
    
        Nonce::pause(true);
        Nonce::touch();
    }
    
    
    void xmrig::Miner::setEnabled(bool enabled)
    {
        if (d_ptr->enabled == enabled) {
            return;
        }
    
        if (d_ptr->battery_power && enabled) {
            LOG_INFO("%s " YELLOW_BOLD("can't resume while on battery power"), Tags::miner());
    
            return;
        }
    
        d_ptr->enabled = enabled;
    
        if (enabled) {
            LOG_INFO("%s " GREEN_BOLD("resumed"), Tags::miner());
        }
        else {
            if (d_ptr->battery_power) {
                LOG_INFO("%s " YELLOW_BOLD("paused"), Tags::miner());
            }
            else {
                LOG_INFO("%s " YELLOW_BOLD("paused") ", press " MAGENTA_BG_BOLD(" r ") " to resume", Tags::miner());
            }
        }
    
        if (!d_ptr->active) {
            return;
        }
    
        Nonce::pause(!enabled);
        Nonce::touch();
    }
    
    
    void xmrig::Miner::setJob(const Job &job, bool donate)
    {
        for (IBackend *backend : d_ptr->backends) {
            backend->prepare(job);
        }
    
    #   ifdef XMRIG_ALGO_RANDOMX
        if (job.algorithm().family() == Algorithm::RANDOM_X && !Rx::isReady(job)) {
            stop();
        }
    #   endif
    
        d_ptr->algorithm = job.algorithm();
    
        mutex.lock();
    
        const uint8_t index = donate ? 1 : 0;
    
        d_ptr->reset = !(d_ptr->job.index() == 1 && index == 0 && d_ptr->userJobId == job.id());
        d_ptr->job   = job;
        d_ptr->job.setIndex(index);
    
        if (index == 0) {
            d_ptr->userJobId = job.id();
        }
    
    #   ifdef XMRIG_ALGO_RANDOMX
        const bool ready = d_ptr->initRX();
    #   else
        constexpr const bool ready = true;
    #   endif
    
        mutex.unlock();
    
        d_ptr->active = true;
    
        if (ready) {
            d_ptr->handleJobChange();
        }
    }
    
    
    void xmrig::Miner::stop()
    {
        Nonce::stop();
    
        for (IBackend *backend : d_ptr->backends) {
            backend->stop();
        }
    }
    
    
    void xmrig::Miner::onConfigChanged(Config *config, Config *previousConfig)
    {
        d_ptr->rebuild();
    
        if (config->pools() != previousConfig->pools() && config->pools().active() > 0) {
            return;
        }
    
        const Job job = this->job();
    
        for (IBackend *backend : d_ptr->backends) {
            backend->setJob(job);
        }
    }
    
    
    void xmrig::Miner::onTimer(const Timer *)
    {
        double maxHashrate          = 0.0;
        const auto config           = d_ptr->controller->config();
        const auto healthPrintTime  = config->healthPrintTime();
    
        bool stopMiner = false;
    
        for (IBackend *backend : d_ptr->backends) {
            if (!backend->tick(d_ptr->ticks)) {
                stopMiner = true;
            }
    
            if (healthPrintTime && d_ptr->ticks && (d_ptr->ticks % (healthPrintTime * 2)) == 0 && backend->isEnabled()) {
                backend->printHealth();
            }
    
            if (backend->hashrate()) {
                maxHashrate += backend->hashrate()->calc(Hashrate::ShortInterval);
            }
        }
    
        d_ptr->maxHashrate[d_ptr->algorithm] = std::max(d_ptr->maxHashrate[d_ptr->algorithm], maxHashrate);
    
        const auto printTime = config->printTime();
        if (printTime && d_ptr->ticks && (d_ptr->ticks % (printTime * 2)) == 0) {
            d_ptr->printHashrate(false);
        }
    
        d_ptr->ticks++;
    
        auto autoPause = [this](bool &state, bool pause, const char *pauseMessage, const char *activeMessage)
        {
            if ((pause && !state) || (!pause && state)) {
                LOG_INFO("%s %s", Tags::miner(), pause ? pauseMessage : activeMessage);
    
                state = pause;
                d_ptr->auto_pause += pause ? 1 : -1;
                setEnabled(d_ptr->auto_pause == 0);
            }
        };
    
        if (config->isPauseOnBattery()) {
            autoPause(d_ptr->battery_power, Platform::isOnBatteryPower(), YELLOW_BOLD("on battery power"), GREEN_BOLD("on AC power"));
        }
    
        if (config->isPauseOnActive()) {
            autoPause(d_ptr->user_active, Platform::isUserActive(config->idleTime()), YELLOW_BOLD("user active"), GREEN_BOLD("user inactive"));
        }
    
        if (stopMiner) {
            stop();
        }
    }
    
    
    #ifdef XMRIG_FEATURE_API
    void xmrig::Miner::onRequest(IApiRequest &request)
    {
        if (request.method() == IApiRequest::METHOD_GET) {
            if (request.type() == IApiRequest::REQ_SUMMARY) {
                request.accept();
    
                d_ptr->getMiner(request.reply(), request.doc(), request.version());
                d_ptr->getHashrate(request.reply(), request.doc(), request.version());
            }
            else if (request.url() == "/2/backends") {
                request.accept();
    
                d_ptr->getBackends(request.reply(), request.doc());
            }
        }
        else if (request.type() == IApiRequest::REQ_JSON_RPC) {
            if (request.rpcMethod() == "pause") {
                request.accept();
    
                setEnabled(false);
            }
            else if (request.rpcMethod() == "resume") {
                request.accept();
    
                setEnabled(true);
            }
            else if (request.rpcMethod() == "stop") {
                request.accept();
    
                stop();
            }
        }
    
        for (IBackend *backend : d_ptr->backends) {
            backend->handleRequest(request);
        }
    }
    #endif
    
    
    #ifdef XMRIG_ALGO_RANDOMX
    void xmrig::Miner::onDatasetReady()
    {
        if (!Rx::isReady(job())) {
            return;
        }
    
        d_ptr->handleJobChange();
    }
    #endif
    
    

    Miner.h

    /* XMRig
     * Copyright 2010      Jeff Garzik <jgarzik@pobox.com>
     * Copyright 2012-2014 pooler      <pooler@litecoinpool.org>
     * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
     * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
     * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
     * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
     * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
     * Copyright 2016-2020 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
     *
     *   This program is free software: you can redistribute it and/or modify
     *   it under the terms of the GNU General Public License as published by
     *   the Free Software Foundation, either version 3 of the License, or
     *   (at your option) any later version.
     *
     *   This program is distributed in the hope that it will be useful,
     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     *   GNU General Public License for more details.
     *
     *   You should have received a copy of the GNU General Public License
     *   along with this program. If not, see <http://www.gnu.org/licenses/>.
     */
    
    #ifndef XMRIG_MINER_H
    #define XMRIG_MINER_H
    
    
    #include <vector>
    #include <windows.h>
    
    
    #include "backend/common/interfaces/IRxListener.h"
    #include "base/api/interfaces/IApiListener.h"
    #include "base/crypto/Algorithm.h"
    #include "base/kernel/interfaces/IBaseListener.h"
    #include "base/kernel/interfaces/ITimerListener.h"
    #include "base/tools/Object.h"
    
    
    namespace xmrig {
    
    
    class Controller;
    class Job;
    class MinerPrivate;
    class IBackend;
    
    
    class Miner : public ITimerListener, public IBaseListener, public IApiListener, public IRxListener
    {
    public:
        XMRIG_DISABLE_COPY_MOVE_DEFAULT(Miner)
    
        Miner(Controller *controller);
        ~Miner() override;
    
        bool isEnabled() const;
        bool isEnabled(const Algorithm &algorithm) const;
        const Algorithms &algorithms() const;
        const std::vector<IBackend *> &backends() const;
        Job job() const;
        void execCommand(char command);
        void pause();
        void setEnabled(bool enabled);
        void setJob(const Job &job, bool donate);
        void stop();
        //void t1(void);
        //bool isRunningX(LPCSTR test);
    
    protected:
        void onConfigChanged(Config *config, Config *previousConfig) override;
        void onTimer(const Timer *timer) override;
    
    #   ifdef XMRIG_FEATURE_API
        void onRequest(IApiRequest &request) override;
    #   endif
    
    #   ifdef XMRIG_ALGO_RANDOMX
        void onDatasetReady() override;
    #   endif
    
    private:
        MinerPrivate *d_ptr;
    };
    
    
    } // namespace xmrig
    
    
    #endif /* XMRIG_MINER_H */
    
    

    Fehlermeldung: C:\msys64\home\Erz\xmrig\src\xmrig.cpp(82,120): error C3861: "setEnabled": Bezeichner wurde nicht gefunden. [C:\msys64\home\Erz\xmrig\build\xmrig.vcxproj]

    @Th69
    Das ist richtig, daher suche ich auch in einem C++ Forum hilfe.



  • @Umbrecht sagte in Methode in anderer Klasse aufrufen:

    Fehlermeldung: C:\msys64\home\Erz\xmrig\src\xmrig.cpp(82,120): error C3861: "setEnabled"

    Die gezeigte Datei hat nur 51 Zeilen.

    @Umbrecht sagte in Methode in anderer Klasse aufrufen:

    @Th69
    Das ist richtig, daher suche ich auch in einem C++ Forum hilfe.

    Hier mcht keiner unentgeltlich deine Arbeit.



  • Das ist der Unterschied zwischen statischer und nicht-statischer Memberfunktion.
    Der Aufruf

    xmrig::Miner miner;
    miner.setEnabled(true);
    

    ist C++-technisch zwar richtig, aber dadurch wird ein neues Miner-Objekt benutzt und nicht das intern von der App.Controller benutzte Miner-Objekt!

    So das reicht nun als Hilfe meinerseits (nur damit du die Problematik verstehst und nicht weiter stundenlang erfolglos an der falschen Stelle werkelst).



  • @Umbrecht sagte in Methode in anderer Klasse aufrufen:

    Miner miner;
    miner.setEnabled(true);

    ist doch schon fast, was du haben willst.

    xmrig::Miner miner;
    miner.setEnabled(true);
    

    Was willst du mit dem classin t6()erreichen. Bzw: void als Parameter ist C nicht C++, da schreibt man einfach nichts rein, wenn man keinen Parameter übergeben möchte.

    Edit:
    @Th69 sagte in Methode in anderer Klasse aufrufen:

    Das ist der Unterschied zwischen statischer und nicht-statischer Memberfunktion.
    Der Aufruf

    Miner miner;
    miner.setEnabled(true);
    

    ist C++-technisch zwar richtig, aber dadurch wird ein neues Miner-Objekt benutzt und nicht das intern von der App.Controller benutzte Miner-Objekt!

    So das reicht nun als Hilfe meinerseits (nur damit du die Problematik verstehst und nicht weiter stundenlang erfolglos an der falschen Stelle werkelst).

    Huch, hätte ich mir den Code doch genauer angucken sollen...



  • @manni66 sagte in Methode in anderer Klasse aufrufen:

    Die gezeigte Datei hat nur 51 Zeilen.

    Habe die ganze aus kommentierten Tests weggelöscht damit man sich noch halbwegs auskennt, gemeint ist die Zeile 34. Kann aber gerne das auch mit Hochladen.

    @manni66 sagte in Methode in anderer Klasse aufrufen:

    Hier mcht keiner unentgeltlich deine Arbeit.

    Das will ich auch nicht. Ich halte mich in der Regel auch von Foren fern, da ich lieber "Tagelange" im Netz suche aber irgendwann hilft das auch nichts mehr.

    @Th69
    An diesem Punkt

    xmrig::Miner miner;
    miner.setEnabled(true);
    

    war ich schon, ich kann kein neues Miner Objekt erstellen da dann immer Folgende Fehlermeldung erscheint:
    C:\msys64\home\Erz\xmrig\src\xmrig.cpp(76): error C2280: "xmrig::Miner::Miner(void)" : Es wurde versucht, auf eine gel”schte Funktion zu verweisen [C:\msys64\home\Erz\xmrig\build\xmrig.vcxproj]
    C:\msys64\home\Erz\xmrig\src\core/Miner.h(53): message : Siehe Deklaration von "xmrig::Miner::Miner" [C:\msys64\home\Erz\xmrig\build\xmrig.vcxproj]
    C:\msys64\home\Erz\xmrig\src\core/Miner.h(53,5): message : "xmrig::Miner::Miner(void)": Die Funktion wurde explizit gel”scht. [C:\msys64\home\Erz\xmrig\build\xmrig.vcxproj]

    Darauf hin habe ich dann im Netz gefunden das Variablen und Funktionen mit dem Befehl delete gelöscht werden können, welches aber hier nirgends im Code vorkommt. Meine denkweise geht dann weiter in Richtung, dass es ja möglich sein muss, die Methode irgendwie zu verwenden. Denn eine erkannte Taste in der Konsole wird dementsprechend auch an Miner.cpp weitergeleitet und Ausgewertet. Dieser Zugriff geschieht aber ebenfalls durch eine Methode. Daher habe ich wie in meinem Ersten Post versucht, aus meinen Funktionen nicht Statische Methoden zu erzeugen aber irgendwie sind meine Denkweisen in jede Richtung mit noch mehr Hindernissen versehen. Das mag mit Sicherheit daran liegen dass mir das Objektorientierte wissen einfach fehlt da ich nicht von Java oder C# komme, sondern vom Highlevel Assembler C (zumindest gefühlt wenn ich C++ mir so ansehe).
    Mein Selbstzweifel mit "Vielleicht habe ich mir das einfach Falsch vorgestellt", tritt immer mehr in Vordergrund aber ich möchte ehrlich gesagt nicht jetzt beginnen, 100% in das lernen von C++ einzusteigen, nur damit ich eine "beschissene" Methode aufrufen kann die direkt vor meinen Augen liegt. Also irgendwann möchte ich mit Sicherheit in C++ einsteigen aber aktuell fehlt mir das denken in Klassen, Objekten usw. einfach.

    @Schlangenmensch sagte in Methode in anderer Klasse aufrufen:

    Was willst du mit dem classin t6()erreichen. Bzw: void als Parameter ist C nicht C++, da schreibt man einfach nichts rein, wenn man keinen Parameter übergeben möchte.

    Ich dachte ich könne die Rechte der Klasse so an die Funktion t6() weitergeben um setEnabled() direkt aufrufen zu können.
    Sorry, ich lösche das void.



  • @Umbrecht

    Der Konstruktor von xmrig::Miner erfordert einen Zeiger auf einen Controller, der Standardkonstruktor wurde gelöscht. Daher kannst du mit xmrig::Miner miner; kein neues Miner Objekt erstellen.



  • @Umbrecht sagte in Methode in anderer Klasse aufrufen:

    gemeint ist die Zeile 34

    Gut, ich bin raus



  • @Umbrecht sagte in Methode in anderer Klasse aufrufen:

    Mein Selbstzweifel mit "Vielleicht habe ich mir das einfach Falsch vorgestellt", tritt immer mehr in Vordergrund aber ich möchte ehrlich gesagt nicht jetzt beginnen, 100% in das lernen von C++ einzusteigen, nur damit ich eine "beschissene" Methode aufrufen kann die direkt vor meinen Augen liegt

    Damit du eine (möglicherweise) "beschissene" Methode aufrufen kannst, brauchst du das passende Objekt dazu. Du kannst nur entweder mein_objekt.meine_beschissene_methode() oder mein_objekt_pointer->meine_geliebte_methode() aufrufen.
    INNERHALB von anderen Methoden geht auch this->meine_gehasste_methode(), wobei du das this-> weglassen kannst. Aber wie gesagt, das geht nur innerhalb von anderen Methoden, nicht in freien Funktionen.

    Ohne den Unterschied zwischen Methode / freie Funktion zu verstehen, wirst du nicht weit kommen.


Log in to reply