Byteoperation funktioniert nicht

Gast #1263124
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
Gast #1264083
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?
Gast #1265916
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
#1265925
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
}
Gast #1265955
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.
Gast #1265957
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
Gast #1267123
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren