Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) CPP

Games, Plugins, Utils, Tools, 3rdParty, etc...
prodigy7
Erleuchteter
Erleuchteter
Beiträge: 595
Registriert: Donnerstag 1. Januar 2004, 16:59

Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) CPP

Beitrag von prodigy7 »

Hallo zusammen,

ich möchte gerne den FritzBoxCallMon nachprogrammieren, damit man die Funktionalität problemlos auch wieder in aktuellen Images nutzen kann.

Da ich jetzt nicht so wirlich der Crack in Sachen C / C++ bin, taste ich mich langsam nach vorne.
Soweit habe ich in C mittlerweile eine brauchbare Implementierung gebaut, möchte das ganze aber jetzt doch nochmal in C++ nachbauen, da ich mir erhoffe, dass das ganze etwas einfacher ist.
ich habe nun eine Klasse, mit der ich die Konfigurationsdatei auslesen kann - funktioniert soweit auch ganz gut. Jetzt hab ich versucht, das ganze in eine eigene Datei auszulagern. Hierfür muss ich ja dann eine Header-Datei schreiben, damit das Hauptprogramm weis, wie es die Funktionen/Klassen nutzen kann (stimmt doch so, oder?).

Irgendwie mag das aber nicht so ganz klappen ... momentan lande ich bei:

Code: Alles auswählen

g++ -Wall -ansi -c config.cpp
g++ -Wall -ansi -c fritzboxcallmon.cpp
g++ -Wall -ansi config.o fritzboxcallmon.o -o fritzboxcallmon
fritzboxcallmon.o: In function `main':
fritzboxcallmon.cpp:(.text+0x44): undefined reference to `Config::Config(char const*, char)'
fritzboxcallmon.cpp:(.text+0x7f): undefined reference to `Config::get(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
fritzboxcallmon.cpp:(.text+0x92): undefined reference to `Data::operator std::basic_string<char, std::char_traits<char>, std::allocator<char> >() const'
fritzboxcallmon.cpp:(.text+0x11c): undefined reference to `Config::get(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
fritzboxcallmon.cpp:(.text+0x12f): undefined reference to `Data::operator std::basic_string<char, std::char_traits<char>, std::allocator<char> >() const'
collect2: ld returned 1 exit status
make: *** [fritzboxcallmon] Fehler 1
Ich verstehe es so, dass er nicht weis, wie er die externen Funktionen ansprechen soll. Hab ich irgendwie die Header-Datei falsch definiert oder was läuft hier schief? Die wenigen Zeilen Quellcode hab ich mal unter http://download.prodigy7.de/files/progr ... oxcallmon/ abgelegt, falls jemand gucken mag.
Houdini
Developer
Beiträge: 2183
Registriert: Mittwoch 10. Dezember 2003, 07:59

Re: Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) C

Beitrag von Houdini »

oha,

du darfst im cpp file nicht nochmal die Klasse definieren, es werden dort üblicherweise die Methoden definiert
e.g. so

Code: Alles auswählen

Classname::DoSomething(type param1)
{
...
}
dafür dann im config.cpp die config.h inkludieren
prodigy7
Erleuchteter
Erleuchteter
Beiträge: 595
Registriert: Donnerstag 1. Januar 2004, 16:59

Re: Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) C

Beitrag von prodigy7 »

Okay ... ich "definiere" also einmal im Header wie eine Funktion aussieht und "packe" dann später den Code rein. Bei meiner ersten Variante habe ich also quasi beides auf einmal getan, richtig?

Hab es jetzt mal umgestrickt:

Code: Alles auswählen

#include <fstream>
#include <map>
#include <stdexcept>
#include <sstream>
#include <iostream>

#include "config.h"

Data::Data(const std::string& data) : myData(data) {}

Data::operator int() const
{
    std::stringstream ss(myData);
    int val = 0;
    ss >> val;

    if (ss.fail())
    {
        throw std::runtime_error("Cannot convert to int.");
    }
    return val;
}

Data::operator const char*() const
{
    return myData.c_str();
}

Data::operator std::string() const
{
    return myData;
}

Data::operator bool() const
{
    return myData == "true" || myData == "True" || myData == "TRUE";
}

Config::Config(const char* filename, const char fieldSeparator)
{
    using namespace std;

    fstream file(filename, ios::in);

    if (file)
    {
        string line;

        while (getline(file, line))
        {
            size_t sep = line.find_first_of(fieldSeparator);

            if (sep != string::npos)
            {
                string key   = trim(line.substr(0, sep));
                string value = trim(line.substr(sep + 1));

                if (!key.empty())
                {
                    myConfigItems[key] = Data(value);
                }
            }
        }
    } else
    {
        throw runtime_error("Cannot open config file.");
    }
}

Config::Data get(const std::string& key) const
{
    std::map<std::string, Data>::const_iterator it = myConfigItems.find(key);

    if (it != myConfigItems.end())
    {
        return it->second;
    } else
    {
        throw std::runtime_error("Cannot find config item."); 
    }
}

std:::empty:& operator<<(std:::empty:& os, const Config& config)
{
    for (std::map<std::string, Data>::const_iterator it = config.myConfigItems.begin(); it != config.myConfigItems.end(); ++it)
    {
        const std::string& key = it->first;
        const std::string  val = it->second;
        std::cout << key << "\t" << val << std::endl;
    }

    return os;
}

std::string trim(std::string str)
{
    size_t pos = str.find_first_not_of(" \t\n");

    if (pos != std::string::npos)
    {
        str.erase(0, pos);
    }

    pos = str.find_last_not_of(" \t\n");

    if (pos != std::string::npos)
    {
        str.erase(pos + 1);
    }

    return str;
}

std::map<std::string, Data> myConfigItems;
Jetzt kommt diese Meldung:
g++ -Wall -ansi -c config.cpp
config.cpp:71:1: error: ‘Data’ in class ‘Config’ does not name a type
make: *** [config.o] Fehler 1
Ich nehme an, dass ich

Code: Alles auswählen

Data(const std::string& data = "") : myData(data) {}
in der Header-Datei nicht richtig abgebildet habe, weshalb ihm der Data-Type fehlt, oder?
Houdini
Developer
Beiträge: 2183
Registriert: Mittwoch 10. Dezember 2003, 07:59

Re: Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) C

Beitrag von Houdini »

Code: Alles auswählen

-Config::Data get(const std::string& key) const
+Data Config::get(const std::string& key) const
prodigy7
Erleuchteter
Erleuchteter
Beiträge: 595
Registriert: Donnerstag 1. Januar 2004, 16:59

Re: Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) C

Beitrag von prodigy7 »

Danke Houdini, das wars! Hatte zwar noch 2, 3 kleine Fehler, die habe ich aber fixen können dadurch, dass ich das jetzt verstanden habe.
Dann werde ich mal fleißig weiter Coden :-)
Houdini
Developer
Beiträge: 2183
Registriert: Mittwoch 10. Dezember 2003, 07:59

Re: Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) C

Beitrag von Houdini »

prodigy7
Erleuchteter
Erleuchteter
Beiträge: 595
Registriert: Donnerstag 1. Januar 2004, 16:59

Re: Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) C

Beitrag von prodigy7 »

Cool! Du hast ja schon die ganze Arbeit gemacht ;-) Also wenn du nichts dagegen hast, würde ich deine Arbeit gerne wiederverwenden und einfach nur ein anderes "Target" erstellen mit der Funktionalität von FritzBoxCallMon, welche aber deine Arbeit nutzt. Im Endeffekt pragmatisch gesehen muss dass Rad ja nicht x-mal neu erfunden werden.
Mal schauen, ob ich das mit meinem (noch?!) überschaubaren Wissen in C/C++ hinbekomme, da was zusammen zu backen (mein Ziel durch das "Projekt" ist ja auch, etwas zu lernen in Sachen C/C++) :-)

Was ich beim ersten überfliegen gesehen habe: Zum abgreifen von Infos gehst du direkt über das Webinterface der Fritz!Box, was das ganze sehr fehleranfällig für Firmware-Änderungen macht. Mal darüber nachgedacht, via uPNP zu gehen? Ich hatte mal die ganze Kommunikation zerlegt (Netzwerkverkehr mitgesnifft) und angefangen, daraus eine .NET Bibliothek zu bauen: http://www.ip-phone-forum.de/showthread.php?t=190718

Auf diese Art und Weise kommt man recht komfortabel an die Daten ran ohne die Hintertür zu nehmen. Eigentlich wollte ich eher den Weg dafür ebnen, den USB Remote Anschluss unter Linux nutzbar zu machen (bzw. zumindest weitestgehend zu dokumentieren), aber dann waren auch schon die anderen Funktionen recht schnell entschlüsselt und implementiert.
prodigy7
Erleuchteter
Erleuchteter
Beiträge: 595
Registriert: Donnerstag 1. Januar 2004, 16:59

Re: Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) C

Beitrag von prodigy7 »

Okay, hab gerade gesehen: Die aktuelle Version von vdr-fritzbox greift bereits auf uPNP zu - na dann kann es ja losgehen :-)
Houdini
Developer
Beiträge: 2183
Registriert: Mittwoch 10. Dezember 2003, 07:59

Re: Neu Implementierung: FritzBoxCallMon, Anfängerfrage(n) C

Beitrag von Houdini »

Nur zu,
meine Arbeit bezog sich nur darauf,
- aus dem vdr plugin ein Programm zu machen,
- was den bekannten configfile einliest
- und bei Anruf ein popup auf die Neutrino Boxen senden kann

Die libfritz kann da ja noch mehr