У меня есть существующий проект на C++, который я хотел бы передать в android. К сожалению, программа вызывает ошибку «Fatal signal 7 (SIGBUS)» на Android. Он отлично работает на других платформах (32-битный/64-битный Linux и Windows). Вот часть кода, который вызывает проблему:Выравнивание в проекте андроида NDK
RawMem3::RawMem3(uint8_t packet_version, uint32_t flags, uint64_t packet_id,
uint64_t packet_nr, uint64_t timestamp, vector<uint16_t>& nr_channels,
vector<uint16_t>& samples_per_channel, vector<double>& data) :
size_(0) {
size_ = sizeof(packet_version) + sizeof(size_) + sizeof(flags)
+ sizeof(packet_id) + sizeof(packet_nr) + sizeof(timestamp)
+ nr_channels.size() * sizeof(boost::uint16_t)
+ samples_per_channel.size() * sizeof(boost::uint16_t)
+ data.size() * sizeof(float); // FIXXXXXME ... hardcoded sizeof() !!!!
mem_ = malloc(size_);
uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
*ui8_ptr++ = packet_version;
uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(ui8_ptr);
*ui32_ptr++ = size_;
*ui32_ptr++ = flags;
uint64_t* ui64_ptr = reinterpret_cast<uint64_t*>(ui32_ptr);
*ui64_ptr++ = packet_id;
*ui64_ptr++ = packet_nr;
uint64_t* time_ptr = reinterpret_cast<uint64_t*>(ui64_ptr);
*time_ptr++ = timestamp;
uint16_t* ui16_ptr = reinterpret_cast<uint16_t*>(time_ptr);
for (unsigned int n = 0; n < nr_channels.size(); n++)
*ui16_ptr++ = nr_channels[n];
for (unsigned int n = 0; n < samples_per_channel.size(); n++)
*ui16_ptr++ = samples_per_channel[n];
try {
float* flt_ptr = reinterpret_cast<float*>(ui16_ptr);
for (unsigned int n = 0; n < data.size(); n++)
*flt_ptr++ = numeric_cast<float>(data[n]);
} catch (negative_overflow& e) {
cerr << "RawMem -- Constructor: " << e.what();
} catch (positive_overflow& e) {
cerr << "RawMem -- Constructor: " << e.what();
} catch (bad_numeric_cast& e) {
cerr << "RawMem -- Constructor: " << e.what();
}
Строго говоря, со своей стороны:
uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(ui8_ptr);
*ui32_ptr++ = size_;
*ui32_ptr++ = flags
Я предполагаю, что это проблема выравнивания. Я не специалист в этом, поэтому любые идеи, как я могу это исправить? Я уже пытался изменить packet_version
на uint32_t
. После этого ошибка SIGBUS ушла, однако мое клиентское программное обеспечение предполагает, что packed_version
является uint8_t
. Я не могу изменить код клиента, поэтому мне нужно исправить это по-другому.
Является ли это устройство или эмулятор? Последние ARM-процессоры должны быть в порядке с невыровненной 32-разрядной целой записью (но взорваться с 64-битной записью и поплавками). – fadden
Это устройство (Nexus 4). – tlimbacher