PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++] Unsigned Char Array nach unsigned Short konvertieren


minos5000
2009-02-20, 12:02:02
Hi,

wie der Titel schon sagt, versuche ich gerade ein Char-Array nach Short zu konvertieren, da ich für einen Methodenaufruf in einer .lib ein "const unsigned short*" brauche.

Wenn ich aber mein konvertiertes Short übergebe verhält sich die Methode nicht wie beabsichtigt und ich möchte die C++ Profis hier einmal fragen, ob ich vielleicht bei der Konvertierung etwas falsch gemacht habe.


const unsigned char startupString[] = "someString";
const unsigned short* ss = new unsigned short[sizeof(startupString)];

for(int i = 0; i < sizeof(startupString); i+=1)
{
unsigned short someShort = startupString[i] << 8;
someShort |= startupString[i+1];
memcpy((void*)&ss[i], (void*)&someShort, sizeof(someShort));
}



Vielen Dank

minos

Krishty
2009-02-20, 17:27:31
Zuerst einmal: Möchtest du reine binäre Daten konvertieren?
Wie genau möchtest du das Array denn konvertieren? Möchtest du, dass das neue Array kontinuierlich mit den neuen Daten gefüllt wird?wwww, xxxx, yyyy, zzzz zu wwwwxxxx, yyyyzzzzOder möchtest du, dass die Werte erhalten bleiben und nur zu größeren Datentypen konvertiert werden?wwww, xxxx, yyyy, zzzz zu 0000wwww, 0000xxxx, 0000yyyy, 0000zzzz

Oder könnte es sein, dass die Lib einen Wide-Char-String (http://en.wikipedia.org/wiki/Wide_character) statt einem Ansi-String erwartet?
Dann bekommst du den gewollten String direkt durchconst unsigned short startupString[] = L"someString";Allerdings sollte man dafür wchar_t verwenden … aber wenn die lib fremd ist, kannst du da auch nichts dran ändern.

Mehr Details – verwendete Plattform, Compiler, worum es geht – würden uns helfen, dir zu helfen, es geht nämlich alles erheblich einfacher als in deinem Code :)

Gruß, Ky

minos5000
2009-02-21, 15:25:14
Oder könnte es sein, dass die Lib einen Wide-Char-String (http://en.wikipedia.org/wiki/Wide_character) statt einem Ansi-String erwartet?
Dann bekommst du den gewollten String direkt durchconst unsigned short startupString[] = L"someString";Allerdings sollte man dafür wchar_t verwenden … aber wenn die lib fremd ist, kannst du da auch nichts dran ändern.

Mehr Details – verwendete Plattform, Compiler, worum es geht – würden uns helfen, dir zu helfen, es geht nämlich alles erheblich einfacher als in deinem Code :)

Gruß, Ky


Du hast recht, es geht ursprünglich tatsächlich um einen wchar_t. Wenn ich allerdings einen solchen als Parameter übergebe, habe ich immer einen Linkerfehler bekommen. Es gab keinen Fehler wenn ich direkt ein "unsinged short" übergab, was ja das gleiche wie wchar_t sein sollte.

Ich verwende übrigens VS 2008 und die Zielplatform ist WinCE 5.0 (ARMV4I).

Das kuriose war, obwohl die entsprechenden Header in der Zielplatform richtig verlinkt waren, schien VC anscheinend nichts davon zu wissen, dass die beiden Typen identisch sind. Deswegen habe ich auch die Konvertierung versucht. Um eben dieses Problem so zu umgehen.

const unsigned short startupString[] = L"someString"; Das hatte ich auch schon probiert, allerdings bekam ich dann folgende Fehlermeldung: Fehler 1 error C2440: 'Initialisierung': 'const wchar_t [22]' kann nicht in 'const unsigned short []' konvertiert werden ...



Ich konnte das Problem inwischen anderweitig lösen, indem ich in den Projekteinstellungen wchar_t als integrierten Typ behandeln auf "nein" gesetzt habe. Nun bekomme ich keine Linkerfehler mehr und das Programm scheint auch zu laufen.
Normalerweise entwickle ich nicht unter C++ und ehrlichweise hab ich auch keine Ahnung, warum das Ändern dieser Einstellungen den Fehler verschwinden ließ. Aber ich bin heilfroh, dass das Ding endlich läuft.


vg
minos

Krishty
2009-02-21, 15:44:30
Wenn die Option eingeschaltet ist, dann behandelt VS wchar_t nicht als sei es ein typedef eines unsigned shorts, sondern als sei es ein eigener, neuer, nativer Datentyp. Demenstprechend werden auch die Funktionen in Fremdbibliotheken nicht gefunden, wenn sie nicht mit derselben Einstellung kompiliert wurden, weil sie dann nur für unsigned short und nicht für wchar_t existieren.

minos5000
2009-02-21, 15:51:54
Ok, das leuchtet ein. Danke für die Erklärung :)

Ectoplasma
2009-02-23, 14:30:46
Von mir der Hinweis, das die folgende Zeile Code nicht korrekt ist.


unsigned short someShort = startupString[i] << 8


Vielmehr sollte diese wie folgt aussehen.


unsigned short someShort = (unsigned short)startupString[i];


Hier ist sichergestellt, dass der Wide Character das Byte Ordering der Zielplattform erhält, auf dem die CPU gerade läuft. Anders sieht es aus, wenn ein anderes Byte Ordering erwartet wird.

Krishty
2009-02-23, 15:13:12
So wie ich das sehe, wurde da auch versucht, zwei chars in eine short zu quetschen … das hat mich so verunsichert, dass ich garnicht erst auf den Code eingegangen bin … aber um es zu komplettieren:
– Ein Array const zu deklarieren und dann mit memcpy() zu initialisieren ist … ein großes Missverständnis.
– Es handelt sich um C++-Code, also auch static_cast nutzen.
– Die optimale Lösung für so eine Konvertierung wäre imho eh das Erzeugen eines std::wstring aus einem std::string, dann ist man auch völlig carefree was Byte-Order, Freigabe allokierten Speichers usw. angeht.

Ectoplasma
2009-02-23, 17:02:26
– Die optimale Lösung für so eine Konvertierung wäre imho eh das Erzeugen eines std::wstring aus einem std::string, dann ist man auch völlig carefree was Byte-Order, Freigabe allokierten Speichers usw. angeht.

Da stimme ich zu. Nur soweit ich weiss, kann die STL das nicht. Wie sollte sie auch. Sie hat keine Hinweise auf den zu verwendenden Zeichensatz. Aber die Sache interessiert mich auch, vorallem mit welcher (portablen) Bibliothek das zu machen ist.

Krishty
2009-02-23, 17:22:21
Da stimme ich zu. Nur soweit ich weiss, kann die STL das nicht. Wie sollte sie auch. Sie hat keine Hinweise auf den zu verwendenden Zeichensatz.Ich verstehe das Problem nicht – std::wstring ist eine Spezialisierung für wchar_t und der Standard schreibt vor, dass wchar_t aus einem char gewonnen werden kann, indem der zusätzliche Raum mit Nullen gefüllt wird.

Ectoplasma
2009-02-23, 23:50:28
Ich verstehe das Problem nicht – std::wstring ist eine Spezialisierung für wchar_t und der Standard schreibt vor, dass wchar_t aus einem char gewonnen werden kann, indem der zusätzliche Raum mit Nullen gefüllt wird.

Ja stimmt schon. Das kannst du aber auch mit einer einfachen Zuweisung einer char Variablen, zu einer wchar_t Variablen machen. Da passiert genau das Gleiche.

Krishty
2009-02-24, 00:06:24
Ja, nur dass du mit std::string weder Speicher verwalten noch eine Schleife schreiben musst.
Oder habe ich dich falsch verstanden und du hast dich auf die Codepage der chars bezogen? Da weiß ich nämlich ehrlich gesagt garnicht, wie mit Sonderzeichen jenseits der 127 umgegangen wird …