1

POSIX キューから受信したバイトを逆シリアル化する際に少し問題に直面しています。

Python アプリケーションが POSIX キュー データを C アプリケーションにポストし、C がデータを Python Queue に再ポストするモジュールを開発しようとしています。

すべてのデータは Ctype 構造ベースです。

構造定義:

msgStruct.py

MAX_MSG_SIZE = 5120
class MsgStruct(ctypes.Structure):
    _fields_ = [
                ("msgType", ctypes.c_int),
                ("msgSize",ctypes.c_int),
                ("setState",ctypes.c_int),
                ("msgBuf",ctypes.c_char * MAX_MSG_SIZE)
            ]

conversions.py

class conversions():
    def serialize(ctypesObj):
        """
        FAQ: How do I copy bytes to Python from a ctypes.Structure?
        """
        return buffer(ctypesObj)[:]

    def deserialize(ctypesObj, inputBytes):
        """
        FAQ: How do I copy bytes to a ctypes.Structure from Python?
        """
        fit = min(len(inputBytes), ctypes.sizeof(ctypesObj))
        ctypes.memmove(ctypes.addressof(ctypesObj), inputBytes, fit)
        return ctypesObj    

test.py

from mapStruct import *
from conversions import conversions
wrapper=conversions()
data="\x01\x00\x00\x00\x70\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00\x25\x42\x35\x32\x33\x39\x35\x31\x32\x35\x32\x34\x38\x39\x35\x30\x30\x36\x5e\x56\x45\x4e\x4b\x41\x54\x20\x52\x41\x47\x41\x56\x41\x4e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5e\x31\x36\x30\x34\x31\x30\x31\x31\x36\x35\x35\x36\x30\x30\x31\x34\x31\x30\x30\x30\x30\x30\x30\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x35\x32\x33\x39\x35\x31\x32\x35\x32\x34\x38\x39\x35\x30\x30\x36\x3d\x31\x36\x30\x34\x31\x30\x31\x31\x34\x31\x30\x3f\x00\x00...\x00"
"""
Data is the Queue data that is recieved by python
"""
baseStruct=MsgStruct()
rxData=wrapper.deserialize(baseStruct,data)
print rxData.setState # Prints as expected
print rxData.msgType # Prints as expected
print rxData.msgSize
print rxData.msgBuf.encode('hex') # here is probles i dont C any data in this buffer

この問題の解決方法を教えてください。buffer(rxData.msgSize) が常に空であることに非常に驚いており、その理由を知りたいです。

4

2 に答える 2

2

ctypesc_charは、バッファを Python 文字列に変換することで、バッファに役立つようにしようとしています。変換は最初の null バイトで停止します。データ バッファー内のデータの最初の数バイトを変更するとどうなるかを観察します。

0
1
368
b'\x01\x02'

代わりにのタイプを に変更して、msgBuf「役立つ」ようにしようとせず、次のようにデータを 1 文字ずつ調べます。c_ubytectypes

>>> print repr(''.join(chr(x) for x in rxData.msgBuf))
'\x00\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00%B5239512524 ...

しかし、使用する理由はまったくありませんctypes:

import struct

data=b"\x01\x00\x00\x00\x70\x01\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00\x25\x42\x35\x32\x33\x39\x35\x31\x32\x35\x32\x34\x38\x39\x35\x30\x30\x36\x5e\x56\x45\x4e\x4b\x41\x54\x20\x52\x41\x47\x41\x56\x41\x4e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5e\x31\x36\x30\x34\x31\x30\x31\x31\x36\x35\x35\x36\x30\x30\x31\x34\x31\x30\x30\x30\x30\x30\x30\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x35\x32\x33\x39\x35\x31\x32\x35\x32\x34\x38\x39\x35\x30\x30\x36\x3d\x31\x36\x30\x34\x31\x30\x31\x31\x34\x31\x30\x3f\x00\x00...\x00"

msg_offset = struct.calcsize('iii')
print struct.unpack_from('iii',data)
print repr(data[msg_offset:])

出力:

(1, 368, 0)
'\x01\x02\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00%B5239512524895006^VENKAT RAGAVAN            ^16041011655600141000000?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;5239512524895006=16041011410?\x00\x00...\x00'
于 2012-12-24T20:01:25.937 に答える
0

を使用structして、データを解凍できます。

import struct
import ctypes

class MsgStruct(ctypes.Structure):
    _fields_ = [
                ("msgType", ctypes.c_int),
                ("msgSize",ctypes.c_int),
                ("setState",ctypes.c_int),
                ("msgBuf",ctypes.c_char * 5120)
            ]

def deserialize(data):
    sz = len(data)-struct.calcsize('iii')
    return MsgStruct(*struct.unpack('iii{}s'.format(sz), data))

データでテストする:

In [18]: data
Out[18]: '\x01\x00\x00\x00p\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00%B5239512524895006^VENKAT RAGAVAN            ^16041011655600141000000?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;5239512524895006=16041011410?\x00\x00...\x00'

In [19]: s = deserialize(data)

In [20]: s.
s.msgBuf    s.msgSize   s.msgType   s.setState  

In [20]: s.msgType
Out[20]: 1

In [21]: s.msgSize
Out[21]: 368

In [22]: s.setState
Out[22]: 0

編集:割り当てはフィールドMsgStructでは機能しませんmsgBuf。理由については、この質問への回答を参照してください。構造体のアンパックはうまくいきます:

In [13]: sz=12

In [14]: struct.unpack('iii{}s'.format(len(data)-sz), data)
Out[14]: (1, 368, 0, '\x00\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00%B5239512524895006^VENKAT RAGAVAN            ^16041011655600141000000?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;5239512524895006=16041011410?\x00\x00...\x00')
于 2012-12-24T18:39:05.890 に答える