Forum: PC-Programmierung Byteoperation funktioniert nicht


von Markus (Gast)


Lesenswert?

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

von yalu (Gast)


Lesenswert?

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?

von Markus (Gast)


Lesenswert?

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

von Thomas K. (muetze1)


Lesenswert?

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
}

von yalu (Gast)


Lesenswert?

> 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.

von Sven P. (Gast)


Lesenswert?

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

von Markus (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.