Einen unbekannte Struktur als void* behandeln



  • Also ich würde gerne eine Funktion schreiben die beliebige Strukturen als void* übergeben bekommt den Speicherbereich dieser Strukturen in einen neu reservierten kopiert und dort nummerisch verschlüsselt und dann den Zeiger auf den neuen Speicher zurück gibt. Wäre folgener Funktionskopf günstig? :
    void* my_encrypt_func(void* v, long size);

    Wenn ja ist die Frage wie kann ich diesen Speicherbereich quasi einlesen
    und ein Zahlenformat bringen. Irgendeinen hexadezimalen Wert müssen die doch haben oder? Ich bin da leider kein Experte, aber mein logisches Verständniss sagt mir das ich auf dieser Ebene ansetzen muss.

    Also als Beispiel:
    char* c = new[30]; void* my_pointer encrypt(c, (void*)strlen(c)+1);

    Ich habe nun eine Anfangsadresse und eine Länge. Was das ursprünglich mal war darf mich garnicht interssieren deshalb der void* pointer als Parameter.
    Niemand soll sich die Mühe machen mir hier was vorzucoden, das schaffe ich schon obwohl jeder Schnipsel hilferich wäre. Ich habe nur von diesen Speichergeschichten und deren Auslese-und Manipulationsmöglichen via mempcpy oder printf usw. keine Ahnung leider.



  • Mal so ne Frage: Warum castest du dein strlen nach void* wenn deine Funktion ein long erwartet?

    memcopy funktioniert folgendermassen:

    int i[20], j[20];
    memcpy(j, i, 20);
    

    Wa für einen Sinn soll deine Funktion eigentlich machen?



  • 1. sollte man für größen Angaben std::size_t nehmen und nicht int oder long! Da std::size_t an die Platformangepasst ist (und du wenn std::size_t < long ist oä. Probleme bekommen kannst!)

    2. Ist diese Funktion doch ein gutes Beispiel für Templates

    http://www.schornboeck.net/ckurs/generisch.htm

    3. Hier mal ein bissel Pseudo Code für dich

    char *data=new char[sizeof(T)]; //T ist der Typ des Parameters, wenn du Templates nimmst, ansonsten musst du sizeof(T) durch long ersetzen
    memcpy(data,v,sizeof(T));
    

    nun kannst du die Bytes in data mit deinem Algorithmus verändern

    (hoffe du verstehst mich :))

    Wa für einen Sinn soll deine Funktion eigentlich machen?

    Was für ein Sinn hat wohl eine Funktion die Objekte verschlüsselt? 🙄 🙂



  • lad_micro schrieb:

    Also ich würde gerne eine Funktion schreiben die beliebige Strukturen als void* übergeben bekommt den Speicherbereich dieser Strukturen in einen neu reservierten kopiert und dort nummerisch verschlüsselt und dann den Zeiger auf den neuen Speicher zurück gibt. Wäre folgener Funktionskopf günstig? :
    void* my_encrypt_func(void* v, long size);

    Ich wäre für: std::auto_ptr<void> my_encrypt_func(const void* buffer, std::size_t size);

    Dann kann der Benutzer den Buffer nicht so einfach leaken (er sollte aber wissen, wie man mit auto_ptr umgeht...). Noch lieber ist es mir bei solchen Funktionen allerdings, wenn ich meinen eigenen Buffer übergebe und die Funktion da reinschreibt.
    Innerhalb von my_encrypt_func kannst du buffer dann in "const unsigned char*" reinterpret-casten (afaik auch static-casten) und dadurch auf alle Elemente zugreifen.



  • Auch wenn Referenz-gezählte Pointer teuer sein mögen, ich steh nicht so auto_ptr. Lieber lasse ich den Benutzer zwischen boost::shared_ptr und std::auto_ptr entscheiden.



  • int encode(const char*source, int slen, char*dest, int dlen);
    wenn immer sichergestellt ist, dass die ausgabe genauso gross wie die eingabe ist, kann man sich rueckgabewert und dlen sparen.

    OT: jedes mal wenn ich auf antworten klicke, kommt line 315 error 'null' is null or not an object.



  • @Peter
    aber d benutzt auch int fälschlicher weise als std::size_t! Außerdem würde ich einen Cast möglichst weit nach hinten verschieben, also erst in der Funktion durchführen und vorher Template Argumente nehmen



  • Wozu ein Template? Nach void* sind doch eh alle relevanten Zeiger implizit konvertierbar.

    Mr. N schrieb:

    Auch wenn Referenz-gezählte Pointer teuer sein mögen, ich steh nicht so auto_ptr. Lieber lasse ich den Benutzer zwischen boost::shared_ptr und std::auto_ptr entscheiden.

    shared_ptr hat einen auto_ptr-Konstruktor/Zuweisungsoperator 😉
    Aber ich wäre sowieso für den vorallokierten Buffer...



  • Hallo

    Also erstmal:
    Die Funktion soll etwas verschlüsseln und zwar das was Sie übergeben bekommt.
    Der Crypto-Algorithmus ist ein numerischer d.h. ich brauche mehr oder weniger
    gültige Zahlen im rechenbaren Bereich des Long-Datentypes oder dergleichen.
    Da die Funktion mehr oder weniger universell funktionieren soll ohne Überladungen etc. ist das mit dem void* Pointer als Start-Adresse und einer Länge das einzige was mir eingefallen ist(Sofern meine Infos über lineare Adressierung stimmen). Ich muss nun das was ich da übergeben bekommen habe nun also noch in ein Zahlen-Array bringen also den Speicherbereich so wie ich
    Ihn bekommen habe kopieren und in kleine rechenbare Zahlen aufteilen, dann die Zahlen verschlüsseln und einen Zeiger auf mein lustiges neues kleines Array zurückgeben damit eine entsprechende Entschlüsselungsfunktion das bei Zeiten zurückrechnen kann und einen Speicherbereich erzeugt der identisch ist mit dem ursprünglich übergebenden. Wie ich das alles ganz genau mache weiss ich
    ehrlich gesagt auch noch nicht ...

    Zweitens: Mein Funktionskopf den ich da "gemalt" habe ist natürlich Humbug.
    strlen in einen void* casten macht gar keinen Sinn - Sorry.
    So ist's besser
    //Prototyp der Funktion: void* encrypt_func(void* v, size_t size);
    //Use:
    char* c = new[30];
    strcpy(c,"ThanksforHelpMe\0");
    void* my_pointer = encrypt_func((void*)c, strlen(c)+1);

    Ob strlen an der Stelle überhaupt das richtige Mittel ist die korrekte Speicherlänge des Char-Arrays c anzugeben muss ich gleich noch rausfinden.

    Danke an der Stelle für den Tip mit size_t. ich habe das schon mehrmals bei MS-Sample-Code gesehen aber mir irgendwie nie was dabei gedacht. Vielen Dank auch für die anderen Tips.



  • Nach void* braucht man nicht einmal casten. Außerdem ist strlen falsch, weil es einfach von der übergebenen Adresse an nach einem Nullbyte sucht. Du müsstest hier 30 direkt übergeben, weil man von einem char* nicht mehr auf die Größe des angepointerten Speicherbereichs schließen kann.


Anmelden zum Antworten