direkt in std::vector schreiben (als unsigned char**)



  • Hallo Leute,

    kann ich einen std::vector direkt in eine Funktion einstzen, dessen Parameter ein 'unsigned char**' erwartet?

    int size = getSize(...);
    std::vector<unsigned char> storage(size);
    unsigned char *temp = storage.data();
    eineFunktion(&temp);
    

    Das oben genannte Beispiel funktioniert so erstmal. getSize() ist eine einfache Funktion, welche die benötige Speichergröße zurückgibt. Die Funktion 'eineFunktion(unsigned char** ppBuffer)' schreibt dann irgendwelche Daten in den Puffer. Momentan mache ich dies über den Umweg mit der Variable 'temp'. Kann ich das besser zusammenfassen? Die beiden genannten Funktionen sind extern und nicht änderbar.

    prinzipiell hätte ich also gerne so etwas:

    int size = getSize(...);
    std::vector<unsigned char> storage(size);
    eineFunktion(&storage.data());  //error: lvalue required as unary ‘&’ operand
    

    viele Grüße,
    SBond



  • Wozu braucht die Funktion char**? Das ist entweder dämlich implementiert oder macht etwas anderes als du denkst.



  • manni66 schrieb:

    Wozu braucht die Funktion char**? Das ist entweder dämlich implementiert oder macht etwas anderes als du denkst.

    Konkret handelt es sich um diese OpenSSL-Funktion:

    int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
    

    Der Rückgabewert ist die Größe der Daten, die zu kopieren sind. Der erste Parameter ist die Quellstruktur und der 2. Parameter das Ziel, in dem die Daten kopiert werden soll. Das ist in OpenSSL ein gängiges Schema. Man kann den 2. Parameter auf nullptr setzen, wenn man nur die Größe der Daten wissen will.

    Das führt so zu solchem code:

    int size = i2d_PublicKey(pKey, nullptr);
    if (size < 0)
        throw irgendwas;
    
    std::vector<unsigned char> storage(size);
    unsigned char *temp = storage.data();
    i2d_PublicKey(pKey, &temp);
    


  • Du hast die Frage nicht beantwortet. ** braucht die Funktion nur, wenn sie den Puffer selbst bereit stellt.



  • manni66 schrieb:

    Du hast die Frage nicht beantwortet. ** braucht die Funktion nur, wenn sie den Puffer selbst bereit stellt.

    den Puffer stellt die Funktion nicht zur Verfügung (da bin ich mir sehr sicher). Ansonsten hätte als Parameter ein einfaches * gereicht.

    Hier ist mal die Orginalbeschreibung von diesen Funktionen (diese gibt es für verschiedene Typen, sind aber von der Funktionsweise identisch):

    int i2d_X509(X509 *x, unsigned char **out);
    

    i2d_X509() encodes the structure pointed to by x into DER format. If out is not NULL is writes the DER encoded data to the buffer at *out, and increments it to point after the data just written. If the return value is negative an error occurred, otherwise it returns the length of the encoded data.

    https://www.openssl.org/docs/manmaster/crypto/d2i_X509.html



  • SBond schrieb:

    Ansonsten hätte als Parameter ein einfaches * gereicht

    Nein, eben nicht.

    i2d_X509() encodes the structure pointed to by x into DER format. If out is not NULL is writes the DER encoded data to the buffer at *out, and increments it to point after the data just written. If the return value is negative an error occurred, otherwise it returns the length of the encoded data.

    Aha, der Pointer wird geändert und zeigt hinter die kopierten Daten. Dann sollte deine Lösung mit temp funktionieren, wenn der Vector groß genug ist.



  • Stimmt du hat ja Recht! 😮

    Mein Fehler. Das hatte ich ja ganz verdrängt. Ja der Pointer wird natürlich geändert. ...ich dussel.

    vielen Dank, dass du mich wieder wachgerüttelt hast. 🙂


Log in to reply