【问题标题】:Receiving bytes through UDP, cast to struct, then to NSDictionary通过 UDP 接收字节,转换为 struct,然后转换为 NSDictionary
【发布时间】:2018-04-04 20:19:09
【问题描述】:

所以我将一个字节接收到一个 NSData 对象中,我可以使用[data bytes] 读取原始数据我还有一个结构,您可以在下面找到它。

如何将这些数据与结构一起转换为更有用的东西?像 NSDictionary 还是其他对象?

我正在尝试什么:

UDPPacket packet;
packet = [data bytes];

但它返回错误:Assigning to 'UDPPacket' from incompatible type 'const void *'

结构:

typedef struct {
    float m_worldPosition[3]; // world co-ordinates of vehicle
    float m_lastLapTime;
    float m_currentLapTime;
    float m_bestLapTime;
    float m_sector1Time;
    float m_sector2Time;
    float m_lapDistance;
    Byte  m_driverId;
    Byte  m_teamId;
    Byte  m_carPosition;     // UPDATED: track positions of vehicle
    Byte  m_currentLapNum;
    Byte  m_tyreCompound; // compound of tyre – 0 = ultra soft, 1 = super soft, 2 = soft, 3 = medium, 4 = hard, 5 = inter, 6 = wet
    Byte  m_inPits;           // 0 = none, 1 = pitting, 2 = in pit area
    Byte  m_sector;           // 0 = sector1, 1 = sector2, 2 = sector3
    Byte  m_currentLapInvalid; // current lap invalid - 0 = valid, 1 = invalid
    Byte  m_penalties;  // NEW: accumulated time penalties in seconds to be added
} CarUDPData;


typedef struct {
    float m_time;
    float m_lapTime;
    float m_lapDistance;
    float m_totalDistance;
    float m_x; // World space position
    float m_y; // World space position
    float m_z; // World space position
    float m_speed; // Speed of car in MPH
    float m_xv; // Velocity in world space
    float m_yv; // Velocity in world space
    float m_zv; // Velocity in world space
    float m_xr; // World space right direction
    float m_yr; // World space right direction
    float m_zr; // World space right direction
    float m_xd; // World space forward direction
    float m_yd; // World space forward direction
    float m_zd; // World space forward direction
    float m_susp_pos[4]; // Note: All wheel arrays have the order:
    float m_susp_vel[4]; // RL, RR, FL, FR
    float m_wheel_speed[4];
    float m_throttle;
    float m_steer;
    float m_brake;
    float m_clutch;
    float m_gear;
    float m_gforce_lat;
    float m_gforce_lon;
    float m_lap;
    float m_engineRate;
    float m_sli_pro_native_support; // SLI Pro support
    float m_car_position; // car race position
    float m_kers_level; // kers energy left
    float m_kers_max_level; // kers maximum energy
    float m_drs; // 0 = off, 1 = on
    float m_traction_control; // 0 (off) - 2 (high)
    float m_anti_lock_brakes; // 0 (off) - 1 (on)
    float m_fuel_in_tank; // current fuel mass
    float m_fuel_capacity; // fuel capacity
    float m_in_pits; // 0 = none, 1 = pitting, 2 = in pit area
    float m_sector; // 0 = sector1, 1 = sector2, 2 = sector3
    float m_sector1_time; // time of sector1 (or 0)
    float m_sector2_time; // time of sector2 (or 0)
    float m_brakes_temp[4]; // brakes temperature (centigrade)
    float m_tyres_pressure[4]; // tyres pressure PSI
    float m_team_info; // team ID
    float m_total_laps; // total number of laps in this race
    float m_track_size; // track size meters
    float m_last_lap_time; // last lap time
    float m_max_rpm; // cars max RPM, at which point the rev limiter will kick in
    float m_idle_rpm; // cars idle RPM
    float m_max_gears; // maximum number of gears
    float m_sessionType; // 0 = unknown, 1 = practice, 2 = qualifying, 3 = race
    float m_drsAllowed; // 0 = not allowed, 1 = allowed, -1 = invalid / unknown
    float m_track_number; // -1 for unknown, 0-21 for tracks
    float m_vehicleFIAFlags; // -1 = invalid/unknown, 0 = none, 1 = green, 2 = blue, 3 = yellow, 4 = red
    float m_era;                     // era, 2017 (modern) or 1980 (classic)
    float m_engine_temperature;   // engine temperature (centigrade)
    float m_gforce_vert; // vertical g-force component
    float m_ang_vel_x; // angular velocity x-component
    float m_ang_vel_y; // angular velocity y-component
    float m_ang_vel_z; // angular velocity z-component
    Byte  m_tyres_temperature[4]; // tyres temperature (centigrade)
    Byte  m_tyres_wear[4]; // tyre wear percentage
    Byte  m_tyre_compound; // compound of tyre – 0 = ultra soft, 1 = super soft, 2 = soft, 3 = medium, 4 = hard, 5 = inter, 6 = wet
    Byte  m_front_brake_bias;         // front brake bias (percentage)
    Byte  m_fuel_mix;                 // fuel mix - 0 = lean, 1 = standard, 2 = rich, 3 = max
    Byte  m_currentLapInvalid;     // current lap invalid - 0 = valid, 1 = invalid
    Byte  m_tyres_damage[4]; // tyre damage (percentage)
    Byte  m_front_left_wing_damage; // front left wing damage (percentage)
    Byte  m_front_right_wing_damage; // front right wing damage (percentage)
    Byte  m_rear_wing_damage; // rear wing damage (percentage)
    Byte  m_engine_damage; // engine damage (percentage)
    Byte  m_gear_box_damage; // gear box damage (percentage)
    Byte  m_exhaust_damage; // exhaust damage (percentage)
    Byte  m_pit_limiter_status; // pit limiter status – 0 = off, 1 = on
    Byte  m_pit_speed_limit; // pit speed limit in mph
    float m_session_time_left;  // NEW: time left in session in seconds
    Byte  m_rev_lights_percent;  // NEW: rev lights indicator (percentage)
    Byte  m_is_spectating;  // NEW: whether the player is spectating
    Byte  m_spectator_car_index;  // NEW: index of the car being spectated

    // Car data
    Byte  m_num_cars;               // number of cars in data
    Byte  m_player_car_index;         // index of player's car in the array
    CarUDPData  m_car_data[20];   // data for all cars on track
    float m_yaw;  // NEW (v1.8)
    float m_pitch;  // NEW (v1.8)
    float m_roll;  // NEW (v1.8)
    float m_x_local_velocity;          // NEW (v1.8) Velocity in local space
    float m_y_local_velocity;          // NEW (v1.8) Velocity in local space
    float m_z_local_velocity;          // NEW (v1.8) Velocity in local space
    float m_susp_acceleration[4];   // NEW (v1.8) RL, RR, FL, FR
    float m_ang_acc_x;                 // NEW (v1.8) angular acceleration x-component
    float m_ang_acc_y;                 // NEW (v1.8) angular acceleration y-component
    float m_ang_acc_z;                 // NEW (v1.8) angular acceleration z-component
} UDPPacket;

【问题讨论】:

  • 哇。这是一个很大的 fscking 结构。似乎不是最好的设计......
  • 忍不住了,伙计!它适用于代码大师的 F1 2017。它是从 UDP 数据包中接收的。哪个很好恕我直言 :) 知道如何将此结构转换为字典吗?
  • UDPPacket const *packet = reinterpret_cast<UDPPacket const *>(data); 不起作用吗?
  • 有趣的事实:C 和 C++ 之间的许多区别之一是在 C++ 中,确实不需要 typedefing structs。 struct CarUDPData { members }; 足以在整个代码中使用 CarUDPData
  • 确保UDPPacket 中的float m_session_time_left; 不会因为32 位对齐float 在一大堆字节中而导致任何填充问题。

标签: c++ objective-c xcode cocoa


【解决方案1】:

与 C 不同,C++ 不允许您在不显式使用强制转换的情况下将 void * 指针隐式转换为另一种类型的指针。

正如杀戮地带小子所说,你可以这样做:

UDPPacket const *packet = reinterpret_cast<UDPPacket const *>(data);

您还需要检查结构是否有填充。通常编译器会在变量之间添加“空格”以保持它们对齐(通常是 4 个字节的倍数)。

如果您愿意,可以使用以下方法禁用它:

#pragma pack(push, 1)
struct UDPPacket {
    // ...
}
#pragma pack(pop)

【讨论】:

  • #pragma 使用注意事项。 #pragma 是一个非标准扩展,如果编译器不支持,编译器可以静默丢弃。您可能会收到编译器警告,但正式情况下由程序员来确保它受到支持。
  • 这会返回 3 个编译器错误:Must use 'struct' tag to refer to type 'UDPPacket'Use of undeclared identifier 'reinterpret_cast'Use of undeclared identifier 'UDPPacket'
猜你喜欢
  • 1970-01-01
  • 2017-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多