Funktion mit variabler Argumentenliste dynamisch aufrufen



  • Hallo Zusammen!

    Ich habe folgendes Problem: Ich möchte eine Funktion, die variable Argumente hat, aufrufen, und zwar dynamisch. Die Parameterwerte, die ich übergeben will, sind Zeiger, die sonst auch dort erwartet werden. Als Beispiel folgende Funktion:

    void testfkt( char* bla, ... )
    {
    	va_list x;
    	char* ptr;
    
    	va_start( x, bla );
    
    	while( ( ptr = va_arg( x, char* ) ) )
    		printf( "%s >%s<\n", bla, ptr );
    
    	va_end( x );
    }
    

    und jetzt der Aufruf, so wie ich es versucht hatte:

    int main( int argc, char** argv )
    {
    	va_list* va;
    
    	va = (va_list*)calloc( 10, sizeof( va_list ) );
    	va[0] = "Das";
    	va[1] = "ist";
    	va[2] = "ein";
    	va[3] = "Test";
    
    	testfkt( "Hallo", *va );
    	return 0;
    }
    

    Es kann auch sein, daß das, was ich versuche, gar nicht geht - da bin ich mir aber nicht wirklich sicher, da ich mich noch nicht genau damit auskenne, wie Parameter in C gehandled werden. 😕

    Gruß
    ~code_pilot



  • So, wie du das versuchst, geht das ziemlich sicher nicht. (und selbst wenn der Compiler das schluckt, glaube ich nicht, daß es ein sinnvolles Ergebnis liefert)

    Für deine Anwendung ist es vermutlich besser, keine variablen Argumente zu verwenden, sondern ganz normale Arrays.



  • CStoll schrieb:

    Für deine Anwendung ist es vermutlich besser, keine variablen Argumente zu verwenden, sondern ganz normale Arrays.

    Naja, das Problem ist, das es die Funktion, die aufgerufen wird, schon gibt, und ich ungern in diesen alten Libraries rumfrickeln möchte. Das könnte ich zwar tun, aber es ist nicht Sinn der Sache 😉 - es sollen an der Toolsbibliothek so gut wie keine Änderungen für mein aktuelles Projekt angestoßen werden.

    Klar wären Arrays hier sinnvoller, aber die hab ich nunmal nicht. Und den Call-Stack der Funktion manipulieren klappt AFAIK so sowieso nicht ;). War ja auch nur ein kläglicher versuch. Und wenn du, CStoll, das schon sagst, ist das nicht ohne Grund denke ich ;).

    Inline-Assembler wäre auch nicht drin, da wir portables C programmieren, was auch auf anderen Plattformen laufen MUSS.

    Danke & Gruß
    ~code_pilot

    PS: Hier => http://www.codeproject.com/cpp/argfunctions.asp steht übrigens, wie die va-Makros funktionieren - danach sehe ich auch ein das es so niemals klappen kann :p



  • Ändere mal

    char* ptr;
    ..
    while( ( ptr = va_arg( x, char* ) ) )
    

    in

    const char* ptr;
    ..
    while( ( ptr = va_arg( x, const char* ) ) )
    

    und dann

    testfkt( "Hallo", "Dies", "ist", "ein", "Test", NULL);
    


  • feigling schrieb:

    Ändere mal

    Du hast mein Problem nicht verstanden.



  • Das mag schon sein, aber dein Code oben ergibt genau 0 Sinn und funktioniert auch nicht. Mein Code tut das, von dem ich denke, dass es dein Code tuen soll. Vielleicht hast du Glück und musst die Funktion garnicht ändern, sondern nur den Aufruf. Ka, ob der unterscheidet zwischen char * und const char *. Und ganz ehrlich? Ich habe mir deinen 2. Post auch garnicht durchgelesen, sondern nur deinen Code.



  • feigling schrieb:

    Das mag schon sein, aber dein Code oben ergibt genau 0 Sinn und funktioniert auch nicht.

    Es geht darum, das ich die Funktion mit variabler Anzahl Aufrufen möchte. Die Anzahl der Argumente weis ich aber nicht wo ich den Code schreibe, sondern er muss zur Laufzeit durch Benutzer-/Datenbankeingaben generiert werden. Daher kann ich nicht pauschal eine feste Anzahl von Argumenten übergeben, ob 3, 6, 19 oder 500. Der Aufruf selber soll DYNAMISCH sein. Aber ich glaube ohne Assembler - was absolut nicht in Frage kommt, da wir portablen Code schreiben - würde man bei diesem Problem nicht herumkommen.

    Gruß
    ~code_pilot



  • Wie ich schon sagte - bei dem Ansatz ist var_arg-Funktionen nicht geeignet. Und wenn du die Zielfunktion nicht umschreiben kannst, könntest du sie eventuell in einer Schleife aufrufen:

    void testfktarr(char* data[])
    {
      int i;
      for(i=0;data[i]!=NULL;++i)
        testfkt(data[i],NULL);
    }
    

    (das klappt natürlich nicht für jede Funktion - printf() auf diese Weise aufzurufen dürfte mächtig in die Hose gehen)



  • CStoll schrieb:

    void testfktarr(char* data[])
    {
      int i;
      for(i=0;data[i]!=NULL;++i)
        testfkt(data[i],NULL);
    }
    

    (das klappt natürlich nicht für jede Funktion - printf() auf diese Weise aufzurufen dürfte mächtig in die Hose gehen)

    Hihi nein das wird nicht gehen, da die Funktion eine Struktur aufbaut, die dann an eine Struktur, die der Funktion übergeben wird, aneghängt wird. Ein erneuter Aufruf würde zu einem Core führen :D, da das alte Strukturelement nicht freigegeben wird (ich liebe meine Software!!! :)). Ergo: Umschreiben.

    Danke aber an Dich.

    ~cp (Currywurst-Pommes)



  • code_pilot schrieb:

    Ein erneuter Aufruf würde zu einem Core führen

    zu einem kern? wessen? des pudels?



  • irre levant schrieb:

    code_pilot schrieb:

    Ein erneuter Aufruf würde zu einem Core führen

    zu einem kern? wessen? des pudels?

    Man merkt, das auf diesem Board nur blöde kleine dumme Kinder anzutreffen sind, die absolut keine Ahnung haben, was das Wort "Compiler" auch nur im Ansatz bedeutet.

    Kennst du eigentlich den Spruch "Wenn man keine Ahnung hat, einfach mal Fresse halten."? Jetzt setzt dich erstmal vor deine X-Box und spiel'ne runde, bevor du noch was sinnvolles lernst.

    ~cp



  • code_pilot schrieb:

    Es geht darum, das ich die Funktion mit variabler Anzahl Aufrufen möchte. Die Anzahl der Argumente weis ich aber nicht wo ich den Code schreibe, sondern er muss zur Laufzeit durch Benutzer-/Datenbankeingaben generiert werden. Daher kann ich nicht pauschal eine feste Anzahl von Argumenten übergeben, ob 3, 6, 19 oder 500. Der Aufruf selber soll DYNAMISCH sein.

    dann ist dein Ansat mit va_list falsch. 1. man sollte nicht va_list an Elipsen übergeben [1] und 2. mit Ellipsen steht schon vor der Kompilierung der Datei die Anzahl der Parameter fest.

    Wenn die Anzahl der Parameter erst zur Lauzeit bekannt ist, dann musst du den Vorschlag von CStoll nehmen: Arrays oder linked lists verwenden.

    [1] Ellipse ist eine Funktion mit belibiger Anzahl von Parametern



  • irre levant spart sich in Zukunft solche Kommentare und code_pilot spart sich solche Reaktionen.


Anmelden zum Antworten