unsigned char als Parameter an eine Funktion übergeben
-
Ich hoffe ich bin hier im richtigen Unterformum. In einem Projekt habe ich ein char-Array mit 32 Elementen.
BYTE pKey[32]; // wobei typedef unsigned char BYTE;
Jetzt muss ich diese Struktur in einer Funktion manipulieren. Vor dem Funktionsaufruf besitzen die Elemente bereits Werte zwischen 0 und 255. Jetzt wollte ich dieser Funktion einen Zeiger oder eine Referenz übergeben, aber ich bekomm das irgendwie nicht hin bzw. sehe den Wald vor lauter Bäumen nicht. Wie kann man das realisieren?
-
#include <iostream> typedef unsigned char BYTE; void print(BYTE *pBuf) { std::cout<< pBuf <<std::endl; } int main() { BYTE pKey[32] = { 'H', 'i' }; print(pKey); }
-
Meinst du so?
typedef unsigned char BYTE; void fkt(BYTE* car) { } int main() { BYTE pKey[32]; getchar(); return 0; }
-
void myfunc(BYTE *arraypointer) { ... } int main() { BYTE pKey[32]; myfunc(pKey); ... }
Wenn nix dagegen spricht, würde ich aber einen Vektor nehmen:
void myfunc(vector<BYTE> &vek) { ... } int main() { vector<BYTE> byteVektor; for(int i = 0; i < 32; ++i) byteVektor.push_back(pKey[i]); myfunc(byteVektor); ... }
-
Also in der Funktion soll folgendes gemacht werden:
srand (static_cast<unsigned int>(time(NULL))); for (int i = 0; i < sizeof(pKey); i++) { pKey[i] = rand()%255; }
Der Knackpunkt liegt bei sizeof(pKey). Ruft man das so auf beträgt es 32 (wie definiert). Übergibt man es wie Kóyaánasqatsi es vergeschlagen hat an eine Funktion, so beträgt sizeof(pKey) nur noch 4, was eben auch einem Byte entspricht.
-
sizeof wird in der Funktion nicht funktionieren, wenn Du mit einem Array arbeitest und einen Pointer auf das erste Element übergibst.
Ein Grund, eine Referenz auf einen Vektor zu übergeben.
-
Wie wär's mit Eigeninitiative?
-
Kóyaánasqatsi schrieb:
Wie wär's mit Eigeninitiative?
Ich hab dein Beispiel getestet und festgestellt, dass es nicht die gewünschte Funktionalität hat.
Belli schrieb:
sizeof wird in der Funktion nicht funktionieren, wenn Du mit einem Array arbeitest und einen Pointer auf das erste Element übergibst.
Ein Grund, eine Referenz auf einen Vektor zu übergeben.
Das Array ist innerhalb der Klasse (nennen wir sie Class A) ein public-Member und wird von weiteren Funktionen dieser Klasse auch genutzt. Eine andere Klasse (nennen wir sie Class
benutzt eben eine Instanz von Class A und soll in einer Funktion dieses Array manipulieren. Mein Gedanke war, einen Zeiger oder eine Referenz zur übergeben, was ja irgendwie nicht geht. Sicher könnte man jetzt das Array in ein CArray oder einen Vector elementweise kopieren, übergeben und nach Abarbeitung der Funktion wieder zurückschreiben. Dies wollte ich aber umgehen.
Belli schrieb:
sizeof wird in der Funktion nicht funktionieren, wenn Du mit einem Array arbeitest und einen Pointer auf das erste Element übergibst.
Und wie übergebe ich einen Zeiger auf die gesamte Struktur?
-
void func(std::tr1::array<unsigned char,32> & referenz); int main() { std::tr1::array<unsigned char,32> key = {{0}}; func(key); }
void func(unsigned char (&referenz)[32]); int main() { unsigned char key[32] = {0}; func(key); }
void func(std::size_t len, unsigned char* zeiger); // #1 template<std::size_t N> inline void func(unsigned char (&referenz)[N]) // #2 { func(N,&referenz[0]); } int main() { const int numelems = 32; unsigned char key[numelems] = {0}; func(numelems,key); // #1 func(key); // #2 --> #1 }
void func(std::vector<unsigned char> & referenz); int main() { const int numelems = 32; std::vector<unsigned char> key (numelems); func(key); }
-
AndyDD schrieb:
Sicher könnte man jetzt das Array in ein CArray oder einen Vector elementweise kopieren, übergeben und nach Abarbeitung der Funktion wieder zurückschreiben. Dies wollte ich aber umgehen.
Das war nur, um das Beispiel möglichst vollständig zu machen. Gemeint habe ich, die Daten von vornherein in einem Vektor zu speichern, und das Array wegzulassen.
Ansonsten bleibt:Die aufgerufenen Funktion 'weiß', daß das Array 32 Elemente hat, dann ist es nicht flexibel - ist sind aber durchaus Fälle vorstellbar, wo das genügt.
Die aufgerufenen Funktion bekommt einen weiteren Parameter, der die aktuelle Anzahl der Arrayelemente enthält.
-
Belli schrieb:
AndyDD schrieb:
Sicher könnte man jetzt das Array in ein CArray oder einen Vector elementweise kopieren, übergeben und nach Abarbeitung der Funktion wieder zurückschreiben. Dies wollte ich aber umgehen.
Das war nur, um das Beispiel möglichst vollständig zu machen. Gemeint habe ich, die Daten von vornherein in einem Vektor zu speichern, und das Array wegzulassen.
Ansonsten bleibt:Die aufgerufenen Funktion 'weiß', daß das Array 32 Elemente hat, dann ist es nicht flexibel - ist sind aber durchaus Fälle vorstellbar, wo das genügt.
Die aufgerufenen Funktion bekommt einen weiteren Parameter, der die aktuelle Anzahl der Arrayelemente enthält.
Mir gehts hier nur um eine grundsätzliche Problemstellung: wie übergebe ich einer Funktion einen Zeiger auf ein char-Array mit [n]-Elementen. Das es anders geht steht außer Frage. Ich finde auch das Design nicht gut. Wenn die Klasse allerdings aus ner dll stammt und man nur den Header hat, dann kann man nicht einfach mal so auf einen Vector umstellen.
-
Tja, wie gesagt, den Zeiger kannst Du so übergeben, allerdings kann die Funktion nicht feststellen, wieviel Elemente das Array hat.
Siehe mein letztes Posting.Noch eine Alternative:
Es gibt ein definiertes letztes Element im Array - so wie das Nullbyte bei einem String-Array.
-
AndyDD schrieb:
Mir gehts hier nur um eine grundsätzliche Problemstellung: wie übergebe ich einer Funktion einen Zeiger auf ein char-Array mit [n]-Elementen.
Wortwörtliche Umsetzung:
const int n = 32; void func(char (*zeiger_auf_array)[n]); int main() { char arr[n] = ""; func(&arr); }
Wenn Dir das nicht passt, musst Du genauer beschreiben, was Du haben willst.
-
Belli schrieb:
Tja, wie gesagt, den Zeiger kannst Du so übergeben, allerdings kann die Funktion nicht feststellen, wieviel Elemente das Array hat.
Siehe mein letztes Posting.Noch eine Alternative:
Es gibt ein definiertes letztes Element im Array - so wie das Nullbyte bei einem String-Array.Leider nein. Die Struktur wird zur Speicherung eines Schlüssels verwendet, der für eine AES-Kodierung gebraucht wird. Leider kann der Benutzer zwischen 16 oder 32 Stellen wählen. Soll heißen, dass ich in einer erweiterten Funktion pKey[16] auch mit berücksichtigen muss. Dies war auch der Grund, warum alles allgemein gehalten werden muss. Aber ich habe grad noch eine Idee:
Wie verhält es sich, wenn ich außerhalb der Funktion sizeof(pKey) aufrufe und dies der Funktion als Parameter mit übergebe? Müsste doch gehen...
Was ich allerdings noch nicht so kapiert habe ist folgendes: mit BYTE* pKey übergebe ich doch einen Zeiger auf das char-Array, richtig? Wieso kann ich dann innerhalb der Funktion ohne den Zeiger zu dereferenzieren auf pKey zugreifen? Würde ich nur ein int-Variable var übergeben, könnte ich innerhalb der funktion darauf nur über *var drauf zugreifen.
-
Lies doch einfach mal ein Tutorial über Arrays und Zeiger.
Ein Anfang dazu wäre die FAQ
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39497.html
-
machma ...
int a[5] = {0,1,2,3,4}; std::cout << a; std::cout << &a[0]; std::cout << *a; std::cout << a[0];
-
AndyDD schrieb:
Wie verhält es sich, wenn ich außerhalb der Funktion sizeof(pKey) aufrufe und dies der Funktion als Parameter mit übergebe? Müsste doch gehen...
Wenn Du
BYTE pKey[n];
definierst, dann gibt sizeof(pKey) n zurück, aber nur innerhalb desselben Scopes. Solltest Du also zB 32 Elemente definieren, aber nur 16 einfüllen, hilft Dir das auch nicht.
Aber in dem Fall brauchst Du ja sizeof gar nicht, Du könntest direkt n übergeben.
Ansonsten klar, wie schon erwähnt, wenn Du der Funktion einen weiteren Parameter mitgeben kannst, der die relevante Anzahl enthält, ist alles klar.AndyDD schrieb:
Was ich allerdings noch nicht so kapiert habe ist folgendes: mit BYTE* pKey übergebe ich doch einen Zeiger auf das char-Array, richtig? Wieso kann ich dann innerhalb der Funktion ohne den Zeiger zu dereferenzieren auf pKey zugreifen? Würde ich nur ein int-Variable var übergeben, könnte ich innerhalb der funktion darauf nur über *var drauf zugreifen.
Wenn ptr ein Zeiger ist, dann ist *ptr == ptr[0].
-
AndyDD schrieb:
Die Struktur wird zur Speicherung eines Schlüssels verwendet, der für eine AES-Kodierung gebraucht wird. Leider kann der Benutzer zwischen 16 oder 32 Stellen wählen. Soll heißen, dass ich in einer erweiterten Funktion pKey[16] auch mit berücksichtigen muss.
Was hindert Dich denn daran, die Länge mitzuübergeben?!
void aes_init_key( aes_context*, int key_len_in_octets, unsigned char const key[]);
AndyDD schrieb:
Dies war auch der Grund, warum alles allgemein gehalten werden muss. Aber ich habe grad noch eine Idee:
Wie verhält es sich, wenn ich außerhalb der Funktion sizeof(pKey) aufrufe und dies der Funktion als Parameter mit übergebe? Müsste doch gehen...Tätäää! Das hat ja lange gedauert. So einen Ansatz gab es auch schon auf der ersten Thread-Seite hier.
AndyDD schrieb:
Was ich allerdings noch nicht so kapiert habe ist folgendes: mit BYTE* pKey übergebe ich doch einen Zeiger auf das char-Array, richtig?
Falsch. BYTE ist kein Array. Dementsprechend ist BYTE* auch kein Zeiger auf ein Array. Aber dieser Zeiger könnte auf das erste Element eines BYTE-Arrays zeigen, ja.
AndyDD schrieb:
Wieso kann ich dann innerhalb der Funktion ohne den Zeiger zu dereferenzieren auf pKey zugreifen?
Also, "pKey" war der unglückglich gewählte Name eines char-Arrays auf Aufruferseite, ja? Antwort: Gar nicht. Eventuell übersiehst Du nur das Dereferenzieren. Ich habe übrigens noch kein gescheites Codebeispiel von Dir gesehen. (hint hint hint)
AndyDD schrieb:
Würde ich nur ein int-Variable var übergeben, könnte ich innerhalb der funktion darauf nur über *var drauf zugreifen.
WTF?! Werd doch mal konkreter. ZB mit einem Code-Beispiel.
kk
-
Braunstein schrieb:
Lies doch einfach mal ein Tutorial über Arrays und Zeiger.
Ein Anfang dazu wäre die FAQ
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39497.htmlVielen Dank für den Link, den Beitrag hatte ich auf die Schnelle nicht gefunden. Er erklärt aber so einiges, was ich (denke ich) jetzt verstanden habe.
krümelkacker schrieb:
Was hindert Dich denn daran, die Länge mitzuübergeben?!
Nichts, ich wollte aber aber innerhalb der Funktion diese Sache abfragen. Sorry, dass ich dem ersten Beispiel damit nicht so eine Beachtung geschenkt habe.
Auch weil ich das nicht kapiert hatte:
krümelkacker schrieb:
AndyDD schrieb:
Was ich allerdings noch nicht so kapiert habe ist folgendes: mit BYTE* pKey übergebe ich doch einen Zeiger auf das char-Array, richtig?
Falsch. BYTE ist kein Array. Dementsprechend ist BYTE* auch kein Zeiger auf ein Array. Aber dieser Zeiger könnte auf das erste Element eines BYTE-Arrays zeigen, ja.
AndyDD schrieb:
Wieso kann ich dann innerhalb der Funktion ohne den Zeiger zu dereferenzieren auf pKey zugreifen?
Also, "pKey" war der unglückglich gewählte Name eines char-Arrays auf Aufruferseite, ja? Antwort: Gar nicht. Eventuell übersiehst Du nur das Dereferenzieren.
Mit der letzten Behauptung hast du gar nicht so unrecht, weil:
//Programm array002.cpp aus FAQ-Beitrag ... cout << *&eingabe[i]; // identisch mit eingabe[i] ...
krümelkacker schrieb:
Ich habe übrigens noch kein gescheites Codebeispiel von Dir gesehen. (hint hint hint)
Was willste denn sehen?
-
AndyDD schrieb:
...
Auch weil ich das nicht kapiert hatte:krümelkacker schrieb:
AndyDD schrieb:
Was ich allerdings noch nicht so kapiert habe ist folgendes: mit BYTE* pKey übergebe ich doch einen Zeiger auf das char-Array, richtig?
Falsch. BYTE ist kein Array. Dementsprechend ist BYTE* auch kein Zeiger auf ein Array. Aber dieser Zeiger könnte auf das erste Element eines BYTE-Arrays zeigen, ja.
AndyDD schrieb:
Wieso kann ich dann innerhalb der Funktion ohne den Zeiger zu dereferenzieren auf pKey zugreifen?
Also, "pKey" war der unglückglich gewählte Name eines char-Arrays auf Aufruferseite, ja? Antwort: Gar nicht. Eventuell übersiehst Du nur das Dereferenzieren.
Mit der letzten Behauptung hast du gar nicht so unrecht, weil:
//Programm array002.cpp aus FAQ-Beitrag ... cout << *&eingabe[i]; // identisch mit eingabe[i] ...
Du meintest wohl eingabe[i] ist identisch mit *(eingabe+i), falls eingabe ein Zeiger ist.
AndyDD schrieb:
krümelkacker schrieb:
Ich habe übrigens noch kein gescheites Codebeispiel von Dir gesehen. (hint hint hint)
Was willste denn sehen?
Nix. Aber ohne Code läuft man Gefahr, aneinander vorbei zu reden.