2016-12-02 23 views
0

私はC++に渡す(未処理のソケットを送信する)生のバイトを表すQMLのJavaScript内に「バイナリ文字列」を持っています。バイナリデータをQMLからC++に渡す

私はこのようなコードを使用していました:

// QML 
onSomeSignal: { 
    var proto = new MyMessage(); // https://github.com/dcodeIO/protobuf.js 
    var bbuf = proto.encode(); // https://github.com/dcodeIO/bytebuffer.js 
    var bytes = bbuf.toBinary(); 
    messageBridge.send(bytes); 
} 
// C++ 
void MessageBridge::send(const QString& data) { 
    if(m_tcpSocket->state() == QAbstractSocket::ConnectedState) { 
     m_tcpSocket->write(encodeVarint32(data.length()).toLocal8Bit()); 
     m_tcpSocket->write(data.toLocal8Bit()); 
    } 
} 

はしかし、私はQStringのにJavaScriptの文字列を翻訳することは、時には(おそらくエンコーディングの)バイトを変えたことを発見しました。

次のコードは機能しますが、バイトバッファをバイナリ文字列に変換してJS配列を変換し、QVariantListに変換してQByteArrayを分割して読み込むのは非効率です。

// QML 
onSomeSignal: { 
    var bytes = (new MyMessage()).encode().toBinary(); 
    var bytea = []; 
    for (var i=bytes.length;i--;) bytea[i] = bytes.charCodeAt(i); 
    messageBridge.send(bytes); 
} 
// C++ 
void MessageBridge::send(const QVariantList& data) { 
    if(m_tcpSocket->state() == QAbstractSocket::ConnectedState) { 
     m_tcpSocket->write(encodeVarint32(data.length()).toLocal8Bit()); 
     m_tcpSocket->write(data.toLocal8Bit()); 
     QByteArray bytes(data.length(),'\0'); 
     for (int i=0; i<data.length(); i++) bytes[i] = data[i].toInt(); 
     m_tcpSocket->write(bytes); 
    } 
} 

私がwrite to a QTcpSocketことができる何かを与える方法で、QT/C++にQML/JavaScriptからByteBufferまたはバイナリ文字列のいずれかを渡すための効率的な方法は何ですか?

+0

私のプロジェクトでは、デバイスとして 'QBuffer'を使って' QDataStream'の周りに 'Data'qmlラッパーを実装しました。' QByteArray、基本タイプの読み書きが実装されています - bool、int、実数、文字列、その他の「データ」。だからprotobufが必要でないならば、あなたはそれをやって使うだけで、それは十分簡単で、Qt apisを使って動作します。 – dtech

+0

@ddriver共有いただきありがとうございます。私の場合、QMLからprotobufを生成し、protobufjsでエンコードして送信しています。したがって、(カスタム)ByteArrayクラスが自分のデータの開始点でなければなりません。 – Phrogz

+0

ベース64エンコーディング文字列を使用してみることができます。 – dtech

答えて

1
// QML 
onSomeSignal: { 
    var bytes = new MyMessage(); 
    messageBridge.send(bytes.toArrayBuffer()); 
} 

と配列バッファはうまくQByteArrayに収まる:

// C++ 
void MessageBridge::send(const QByteBuffer& data) { 
    if (m_tcpSocket->state() == QAbstractSocket::ConnectedState) { 
     m_tcpSocket->write(encodeVarint32(data.size()).toLocal8Bit()); 
     m_tcpSocket->write(data); 
} 

は今QMLでオブジェクトをどのように便利protobuf.jsにC ​​++でQByteBufferから他の道を行く方法を教えてくださいシグナル:

+1

@dirtyfreebooterは、Qt5.8で他のやり方を教えてください。 – MattiasF

1

Qt 5.7では、QByteArrayをC++からQMLに理解できないため、後でC++に戻す以外は、QMLでは役に立たないように、不透明なQVariantにラップします。

Qt 5.8+では、QByteArrayタイプのサポートが追加されています。 C++からQMLにリターン変数またはシグナルパラメータとして渡されると、QByteArrayはArrayBufferに変換されます。これはprotobufのjavascript APIがArrayBuffer型を直接デコードできるので、protobufsに便利です。

+0

ここで5.9.2を使用すると、C++からQMLへのバイト配列を返すと、プロパティがまったくなく、JSから見えるものも使用できない空の不透明なオブジェクトになります。 – dtech

関連する問題