Hallo, ich arbeite mit LabWindows/CVI 9.0.1. Wenn ich zwei char in einen short kopieren will, mache ich das normalerweise so: Cues[iTempVal].cviAchsen[iTempVal_2].AxDelays.sDelayValue = (((short) cTempData[uiDataOffset +57] << 8) | cTempData[uiDataOffset +56]); Aber hier funktioniert das irgendwie net. Wenn ich aber ein memcopy mache: memcpy (&Cues[iTempVal].cviAchsen[iTempVal_2].AxDelays.sDelayValue, &cTempData[uiDataOffset + 56], 2); dann funktioniert das einwandfrei. Liegt das jetzt an mir, oder is da irgendwo im CVI ein Bug? MfG Markus
Ist
iTempVal].cviAchsen[iTempVal_2].AxDelays.sDelayValue
vom Typ short? Dann sollte es eigentlich auch mit der Bitshifterei
funktionieren.
> Aber hier funktioniert das irgendwie net.
Was bedeutet das? Gibt der Compiler einen Fehler aus? Stimmt das
Ergebnis nicht? Wenn ja, hast du ein paar Beispiele dafür?
Hallo, der Zieldatentyp ist ebenfalls short. Es gibt keinen Compilerfehler. Es stimmt nur das Ergebnis nicht, weil nur das Low-Byte eingefügt wird. Das komische ist, dass es ein paar Zeilen weiter oben mit anderen Variablen Funktioniert wie es soll. MfG Markus
Welchen Datentyp nutzt C(++) bei einer Operation? Die des ausgehenden, ersten Operanden. Also hat er ein Byte vor sich und das willst du um 8 Bits nach links shiften. Damit wird es 0 und dann oder dein anderes Byte dazu und du erhälst nur dein Low Byte. Das Ergebnis castest du dann von Byte aus Short und fertig ist. Lösung: Caste vorher cTempData[uiDataOffset +57] auf einen short - also vorher explizit auf einen 16 Bit grossen Datentyp casten und dann kann man auch 8 Bit hochshiften. Oder du baust dir einfach eine kleine Helferfunktion:
1 | short MakeShort(byte h, byte l) |
2 | {
|
3 | return ((short)h << 8) | l; |
4 | }
|
> Lösung: > Caste vorher cTempData[uiDataOffset +57] auf einen short - also vorher Das macht Markus doch. Da in C aber alle Rechenoperationen sowieso mindestens mit int-Breite ausgeführt werden¹, erübrigt sich sogar dieser Cast nach short, und folgendes funktioniert ebenfalls:
1 | Cues[iTempVal].cviAchsen[iTempVal_2].AxDelays.sDelayValue = |
2 | cTempData[uiDataOffset+57] << 8 | cTempData[uiDataOffset+56]; |
Der Cast und die Klammern bei Markus dienen ausschließlich der besseren Lesbarkeit. Ich kann also beim besten Willen keinen Fehler erkennen. Entweder liegt der Fehler woanders im Code, bspw. beim Befüllen des cTempData-Arrays oder bei der Ausgabe des Ergebnisses, oder der Compiler hat tatsächlich einen Bug. ¹) Der Compiler darf nur dann 8-Bit-Operationen verwenden, wenn dies am Ergebnis nichts ändert.
Ich würde mal mehrere Dinge überlegen: 1. Ein char ist nicht immer vorzeichenlos. 2. Ein short hat nicht unbedingt mehr Bits als ein char.
1 | #include <stdio.h> |
2 | |
3 | int main(void) { |
4 | signed char sc1, sc2; |
5 | unsigned char uc1, uc2; |
6 | |
7 | sc1 = uc1 = 0xAA; |
8 | sc2 = uc2 = 0xFF; |
9 | |
10 | int sz = sc1<<8 | sc2; |
11 | int uz = uc1<<8 | uc2; |
12 | printf("sz = %i\nuz = %i\n", sz, uz); |
13 | }
|
1 | sz = -1 |
2 | uz = 43775 |
Danke für eure rege Anteilnahme. Wenn ich das cTempData Array anschaue dann stehen die Daten da schon richtig drin. Sonst würde ja auch der memcopy ein falsches Ergebnis liefern. Ich hab das Problem jetzt auch mal mit dem Support von National Instruments besprochen und denen mein Programm geschickt. Bin gespannt was dabei rauskommt. MfG Markus
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.