String zu Funktionsaufruf umwandeln



  • Hallo,

    ich möchte gern eine Funktion schreiben, die aus 2 oder 3 Strings einen Funktionsaufruf machen kann.

    Um ein einfaches Beispiel zu generieren, habe ich den Befehl "printf" in 2 Teile zerlegt. Nun habe ich diese mit "strcat" wieder zusammengeführt. Als ich dann versucht habe (siehe den auskommentierten Teil) buffer anstelle des printf Befehlt zu nutzen hat dies leider nicht funktioniert, da dies noch immer ein String und keine Funktion ist. Was genau muss ich tun, um daraus eine Funktion zu mache oder wonach kann ich suchen (vermutlich fehlt mir nur das richtige Schlagwort)?

    VG

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main()
    {
        
        const char* str1 = "pri";
        const char* str2 = "ntf";
    
        char buffer[100];
        strcat(strcpy(buffer, str1), str2);
    
        //buffer("Test")
        
        printf("%s\n", buffer);
    
        return 0;
    }
    


  • Hallo @Ollom ,
    verstehe ich Dich richtig, Du willst ein Char-Array "aufrufen"? Also buffer == "printf" ist nur eine Zeichenfolge! Da kannst Du reinschreiben was Du willst, es bleibt eine Zeichenfolge. Der Compiler kann daraus keinen Aufruf ermitteln.


  • Mod

    Das ist nur bedingt möglich. C ist keine dynamische Sprache, sondern das gesamte Programm muss zur Compilierzeit feststehen.

    Was du machen kannst, ist tricksen: Du kannst eine Liste mit den Namen allen Funktionen erstellen, die du unterstützen möchtest. Und zu den Namen speicherst du auch noch einen Zeiger auf diese Funktion ab. Dann kannst du mittels einer Zeichenkette (egal wo die herkommt) nach der Funktion in der Liste suchen, und dann diese Funktion über den zugeordneten Pointer aufrufen.

    Für einfache Funktionsaufrufe ohne Rückgabewert und Parameter ist das noch halbwegs machbar, die Schwierigkeit bestünde hauptsächlich darin, dass C keine native Datenstruktur für ein Mapping von Zeichenketten auf Pointer hat, und man daher eine solche Datenstruktur programmieren müsste.

    Schlimm wird's aber, wenn man noch Argumente für die Funktion hat. Da weiß ich spontan nicht einmal, wie ich das allgemein anstellen würde. Ich wähle daher die eine faule Ausrede, die mir erspart darüber nachzudenken: Das geht weit über deine Kenntnisse hinaus und du suchst besser einen anderen Weg 😜

    Jetzt bist du wahrscheinlich sowieso reichlich verwirrt. Im Endeffekt: Es ist sehr schwer, und geht wenn überhaupt dann nur mit starken Einschränkungen und Trickserei. Wenn du mit so etwas herumspielen möchtest, probier es mit einer dynamischen Interpretersprache wie Python. Da geht so etwas relativ einfach. Dafür haben die dann andere Nachteile (und zwar hauptsächlich, dass solch ein Pythonprogramm 5000x langsamer wäre als in C).



  • Hallo,

    vielen Dank für die Antworten.
    Dann werde ich doch diese riesen Liste anlegen müssen, die die entsprechenden Funktionen bereitstellt. Ich dachte nur es geht auch eleganter... 😕
    Trotzdem Danke!



  • Hallo @Ollom,
    Manchmal hat man ein Problem welches man mit einer Lösung angehen möchte. Kann es sein, dass Du uns so eine Lösung vorstellst?
    Welches Problem möchtest Du denn mit dem "Zusammenbau von Funktionsaufrufen" lösen? Oder wozu brauchst Du so was?

    Wenn Du das also kurz, ggf. etwas losgelöst von Deinem jetzigen Lösungsansatz erzählen könntest, was Du gerade programmierst, kommen ggf. Andere auf ganz andere Lösungen.



  • @SeppJ sagte in String zu Funktionsaufruf umwandeln:

    Dafür haben die dann andere Nachteile (und zwar hauptsächlich, dass solch ein Pythonprogramm 5000x langsamer wäre als in C).

    In der Zeit bis das C-Programm fertig ist, kann man ja schon mit dem Python-Script arbeiten.



  • @Ollom Evtl. hilft dir ein C Interpreter weiter.

    Die machen C zu einer Script-Sprache.
    Ob die einen "eval" Befehl haben, entzieht sich aber meiner Kenntnis.



  • @DirkB sagte in String zu Funktionsaufruf umwandeln:

    Evtl. hilft die ein C Interpreter weiter.

    Also mit ROOT (das ist allerdings C++) ginge das so:

    auto tiv = std::unique_ptr<TInterpreterValue>(gInterpreter->CreateTemporary());
    std::string command = "pri";
    command += "ntf";
    gInterpreter->Evaluate(command.c_str(), *tiv)
    std::cout << tiv->ToString() << '\n';
    

    gibt aus:

    (int (*)(const char *__restrict, ...)) Function @0x7fce881fce10
    

    Und mit tiv->GetAsPointer() kämst du an die Adresse als void*, die du dann umcasten müsstest in einen Pointer mit der korrekten Signatur. Aber was, wenn jemand statt "printf" sowas wie "1+2" eingibt? Dann kommt 3 raus, aber das ist ja kein Funktionspointer. Also ist das noch lange nicht das Ende der Probleme hiermit.

    So will man also NICHT arbeiten!

    @Ollom: ich weiß nicht, was du eigentlich erreichen willst, aber Kommandos zusammensetzen aus Strings ist eigentlich nie der richtige Weg, schon gar nicht, wenn du danach fragen musst. Auch in Python und anderen Scriptsprachen, wo das leichter ginge, macht man sowas nicht (oder nur in spezialgelagerten Sonderfällen, die mir noch nicht untergekommen sind).


Log in to reply