C ++を使用してUDPを介して浮遊点番号をQuartzComposerに送信する

StackOverflow https://stackoverflow.com/questions/7358613

  •  28-10-2019
  •  | 
  •  

質問

の中に 別の質問 ユーザーは、UDPを介してQuartzComposerにデータを送信する方法を提供しました。 QuartzComposerは、それに送信されたバイトデータのパディングに非常にこだわっているようです。特に、送信される各文字の前に「 0 0 0」が必要です。

この問題を解決するために、簡単なPythonプログラムをock笑することができました。

from socket import *

PORT = 50000
N = 3.14159265358

# connect to Quartz Composer on localhost port 50000
s = socket(AF_INET, SOCK_DGRAM)
s.bind(('', 0))
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

for c in str(N):
    out = out + '\0\0\0' + c
s.sendto(out, ('225.0.0.0', PORT))

C ++で実装する必要がある重要なセクションは、フローティングポイント数をパッドするビットです。これは、重要なセクションの簡単なPythonモックアップです。

def padfloat(n):
    out = ''
    for c in str(n):
        out = out + '\0\0\0' + c
    return out

if __name__ == '__main__':
    print(padfloat(3.14159265358))

確かに、私のC ++チョップはそれほどタイトではありませんが、ブーストを使用してUDPを稼働させ、ハードコード化されたメッセージ「0.7」を送信することができました。

//
// Working C++ to Quartz Network Test
// 

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::udp;

enum { max_length = 1024 };

int main(int argc, char* argv[])
{
  try
  {
boost::asio::io_service io_service;

udp::socket s(io_service, udp::endpoint(udp::v4(), 0));

udp::resolver resolver(io_service);
udp::resolver::query query(udp::v4(), "225.0.0.0", "50000");
udp::resolver::iterator iterator = resolver.resolve(query);

using namespace std; // For strlen.

// TODO: alter code to take in any number

for (;;) {
  std::cout << "Press Any Key to send 0.7: ";
  char request[max_length];
  std::cin.getline(request, max_length);
  // size_t request_length = strlen(request);
  char test [] = {0,0,0,'0',0,0,0,'.',0,0,0,'7','\0'};
  s.send_to(boost::asio::buffer(test, 12), *iterator);
  std::cout << "Sent\n";
}
  }
  catch (std::exception& e)
  {
std::cerr << "Exception: " << e.what() << "\n";
  }
  return 0;
}

私が助けを必要とするかなり些細な問題は、浮動小数点数を取り込んで、すべての「 0 0 0」パディングを適切に準備して送信するためのチャーアレイとして適切にフォーマットする方法です。私は醜いことをしようとしていますが、誰かが私にエレガントな修正を私に向けることができれば、少し学ぶことができてとてもうれしいです。

役に立ちましたか?

解決

コンパイラが便利ではありませんが、これで十分です。

  1. 文字列変換を行います
  2. バッファーを4倍のサイズ(ヌル終了のために1つとプラス1)、0に初期化します
  3. 4番目の位置ごとに文字列にコピーします。

ASIOがNullターミネーターがそのサイズの一部であることを期待しているかどうかはわかりませんので、私はあなたの例に従いました。

float float_value = 4.2f;
std::string str = boost::lexical_cast<std::string>(float_value);

std::vector<char> char_buff((str.size() * 4) + 1, 0);

for (size_t i = 0; i < str.size(); i++)
  char_buff[(i * 4) + 3] = str[i];

s.send_to(boost::asio::buffer(&char_buff[0], char_buff.size()), *iterator);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top