-1

既に Python で開発された Android アプリの移植に取り組んでいます。Python プログラムには、完全に理解しようとしている次の行があります。

self.comfd = Serial(...) # from the pySerial API
....
self.buffer  = list(struct.unpack('192H', self.comfd.read(384)))

私が理解していることから、self.comfd.read(384)384 バイトを読み取ってunpack('192H'いて、そのデータから 192 の署名なしのショートをアンパックしています。これは正しいです?

Javaでは、次を使用してバッファを読み取ることができました

SerialPort device = SerialPort(file, baud, flags);
InputStream in = device.getInputStream(); 

私の質問は、入力ストリームを取得したので、Python プログラムが行っているように、署名されていない short を作成するにはどうすればよいですか?

私が試したこと(正しい値を生成していない):

byte[] buffer = new byte[384];
in.read(buffer);
ByteBuffer bb = ByteBuffer.allocate(2);
for (int i = 0; i < buffer.length / 2; i++) {
    bb.put(buffer[i]);
    bb.put(buffer[i + 1]);
    short val = bb.getShort(0);
    System.out.println(val);
    bb.clear();
}

私は何を間違っていますか?助けてくれてありがとう!

編集:ジェイソン C の回答を組み込みましたが、間違ってループしていました。に変更することで

for (int i = 0; i < buffer.length; i=i+2)それは私の問題を解決しました。

4

2 に答える 2

3

char (Java では 16 ビットの符号なし値) を使用できます。たとえば、次のようになります。

byte[] buffer = ...;
ByteBuffer bb = ByteBuffer.wrap(buffer); // don't need to put()
int val = (int)bb.getChar(0);

bb.order() を使用して、ビッグ エンディアンとリトル エンディアンを設定します。

ByteBuffer を使用せずに、2 バイトを int にパックすることもできます (リトル エンディアンを想定)。Java ではバイトは符号付きであるため、シフトする前にバイトを符号なしの値に変換する必要があります。これは、バイトを一時的に short (または int または 0-255 を保持するのに十分な大きさのもの) に格納することで実行できます。

short b0 = (buffer[0] & 255); // trick converts to unsigned
short b1 = (buffer[1] & 255);
int val = b0 | (b1 << 8);

// or just put it all inline:
int val = (buffer[0]&255) | ((buffer[1]&255) << 8);

ビッグエンディアン データの場合は、b0 と b1 を交換するだけです。

それが役立つことを願っています。

于 2013-08-06T17:20:13.320 に答える