Anzeige:
Ergebnis 1 bis 5 von 5

Thema: verrückte funktion

  1. #1
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615

    Question verrückte funktion

    ich habe ein etwas verzwicktes problem, wo ich nicht so sehr weiter weiß. das dumme dabie ist, das sich das problem auch reichlich schlecht beschreiben lässt, aber ich will es trotzdem mal versuchen. :-)

    die vorraussetzung: ich programmiere derzeit eine eigne lib in c++, stelle aber das interface zur lib für c zur verfügung.

    für folgenden funktionsaufruf soll die funktion abgebildet werden:
    (der code ist _nicht_ vollständig!!!)

    enum
    {
    NAME = 5,
    FOO,
    BAR,
    SEMMEL,
    NIX,
    NOCH,
    EIN,
    BEISPIEL
    };

    char *name;
    char *foo;
    char *bar;
    int nix;

    func( NAME, name,
    FOO , foo,
    BAR , bar,
    NIX , nix,
    NULL );

    printf("%s - %s - %s - %u\n", name, foo, bar, nix );

    die vars, die mit enum vergeben werden sind nur bezeichner, um sie in eben etwas auseinander halten zu können.

    ich möchte eben eine funktion haben, die ich einmal aufrufen und mehrere werte gleichzeitig zurückbekomme.
    Oben soll nur als beispiel dienen, ich hätte auch das hier nehmen können:

    func( BAR , bar,
    NIX , nix,
    NULL );

    bislang habe ich das _versucht_ auf diese art zu lösen:

    void func( int code, ... )
    {
    char *_name, bar;
    char *foo = "schlumpf";

    va_list arg;
    va_start( arg, code );

    for( ; ; code = va_arg( arg, int ) )
    {
    switch( code )
    {
    case NAME:
    _name = ( char * )malloc( strlen( foo ) + 1 ); // reserviere mem
    strncpy( _name, foo, strlen( foo ) + 1 ); // zuweisung

    // printf( "%s\n", _name ); // testausgabe

    // und jetzt muß _name noch in den addressraum der orig. var kopiert werden ... NUR WIE??
    (char *)arg[1] = _name; // !segfault!

    break;

    case FOO:
    break;

    case NULL:
    va_end( arg );
    return;
    }
    }
    }

    func() darf hier komplett mittels c++ abgebildet sein, nur der aufruf muß zwingend als c funktion realisierbar sein.

    hat jemand mein problem verstanden? ;-)

    ich glaube, langsam versteh ich das selber nicht mehr ...

    Bodo
    Bodo
    Systemadmistration UNIX

  2. #2
    Registrierter Benutzer
    Registriert seit
    21.01.2001
    Beiträge
    157

    Post

    Hi, ich hab dein Problem zwar nicht verstanden, da du nur beschreibst was Du machst, aber nicht was schiefgeht, aber trotzdem ein Tip:

    Wenn Du ihn C++ etwas programmierst, was spaeter von C benutzt werden soll, darfst Du das extern "C" nicht vergessen, also:
    Code:
    #ifdef __cplusplus
      extern "C" {
    endif 
    void func(bla, ...);
    ...
    #ifdef __cplusplus
      }
    endif
    statt nur
    Code:
    void func(bla, ...);

  3. #3
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615

    Post

    was schiefgeht, ist relativ einfach ...
    ich den übergebenen variablen steht einfach nicht's drin.
    ich weiß nicht, wie ich - ohne die variable direkt mit dem funktionsaufruf zu übergeben - in diese was speichern/übergeben kann

    Bodo
    Bodo
    Systemadmistration UNIX

  4. #4
    Registrierter Benutzer
    Registriert seit
    21.01.2001
    Beiträge
    157

    Post

    Hab ich wohl etwas zu schnell gelesen ;-)
    Du willst die Werte kriegen nicht setzen, aha.

    C hat eine "call by value" Semantik und da es die Referenzen aus C++ nicht kennt muss Du wohl mit Pointern arbeiten um "call by reference" zu kriegen.

    Will ja jetzt nicht boese klingen, aber wenn Dir das entgangen sein sollte, dann besorg Dir erstmal ein Buch zu C/C++ ;-)

    Code:
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <stdarg.h> 
    
    enum {
      NAME = 5,
      NIX
    };
    
    void func( int code, ... ) {
      char *_name;
      char *foo = "schlumpf";
    
      int end;
      va_list ap;
      va_start( ap, code );
      
      for( end = 0; !end ; code = va_arg( ap, int ) ) {
        switch( code ) {
        case NAME:
          _name = ( char * )malloc( strlen( foo ) + 1 ); 
          /* DONT USE THIS: strncpy( _name, foo, strlen( foo ) + 1 ); */
          /* false security: 
    	   strncpy( ..., foo, strlen( foo) +1 )
    	 is nothing else than
               strcpy( ..., foo);
          */
          strcpy( _name, foo);
          /* va_arg must be used here, too */
          *(va_arg(ap, char**)) = _name; 
          break;
        case NIX:
          /* va_arg must be used here, too */
          *(va_arg(ap, int*)) = 42;       
          break;      
        case NULL:
          end = 1;
          break;
        default:
          /* FIXME error handling */
        }
      }
      va_end( ap );
    }
    
    int main(){
      char *name;
      int nix;
    
      /* call with address of variable instead of value.
         If we dereference this address as a pointer inside of func()
         we will be able to change the value 
      */
      func( NAME, &name,
    	NIX , &nix,
    	NULL );
      
      printf("%s - %u\n", name, nix );
    
      /* don´t forget to free allocated memory */
      free(name);
    }
    [ 19. Mai 2001: Beitrag editiert von: jgbauman ]

  5. #5
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615

    Post


    Stimmt, den das setzen habe ich ja schon gerafft
    aber diesmal bin ich wohl an der zeigeraritmetik gescheitert ... und zwar massiv!

    Doch dnake für deine hilfe!!!

    Bodo
    Bodo
    Systemadmistration UNIX

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •