У меня три приложения.
Feeder
- создает объект boost::interprocess
shared memory и заполняет его. Feeder
основан на Qt.Gui
- имеет множество кнопок и текстовых полей, из которых создается структурированная конфигурация. Gui
основан на Qt.User
- читает конфигурацию, созданную Gui
и подключается к общей памяти, заполненной Feeder
, а затем выполняет вычисления. User
- консоль C++, без Qt. Проблема в том, что как только Feeder
заполняет общую память, Gui
МОЖЕТ получить доступ к ней, а User
НЕ МОЖЕТ, несмотря на то, что Gui
и User
используют тот же код для чтения разделяемой памяти. Два года назад, с Qt 4.X, это сработало хорошо, сегодня я на Qt 5.1.1. - Я не знаю, есть ли связь с Qt-версией.
Для иллюстрации, фрагменты кода
Feeder
this->mem = new shared_memory_object(create_only, "tickChartSize", read_write);
this->mem ->truncate(sizeof(unsigned int));
mapped_region region( *this->mem, read_write);
*((unsigned int))region.get_address()) = this->size();
Gui
+ User
shared_memory_object *mem = new shared_memory_object(open_only, "tickChartSize", read_only);
this->u = (void*)new mapped_region( *mem, read_only ); // works in Gui, throws in User
Я пошел в код повышения и обнаружил линию, которая отличается от Gui
и User
, прямо перед броском в User
строке 459 в mapped_region.hpp
//Obtain mapping size if user provides 0 size
if(size == 0){
offset_t mapping_size;
THIS --> if(!winapi::get_file_mapping_size(native_mapping_handle, mapping_size)){
error_info err = winapi::get_last_error();
throw interprocess_exception(err);
}
//This can throw
priv_size_from_mapping_size(mapping_size, offset, page_offset, size);
}
Как только вызов winapi::get_file_mapping_size
завершен, mapping_size
в Gui
равен 8, а в User
- -3689348814741910324. Единственная информация об ошибке - в структуре err
, но err.m_ec = system_error(1)
, то есть это сообщение не дает большой поддержки.
Информация о строительстве:
Любая помощь по этому вопросу очень ценится.
Даниил
РЕДАКТИРОВАТЬ - РЕШЕНИЕ
Несмотря на то, что мой оригинальный проект VS работал без каких-либо очевидных ошибок, создание проекта заново привело к исчезновению этого поведения. Спасибо всем зрителям.
Реализация win32 продолжает использовать NtQuerySection для получения размера отображения:
inline bool get_file_mapping_size(void *file_mapping_hnd, __int64 &size)
{
NtQuerySection_t pNtQuerySection =
(NtQuerySection_t)dll_func::get(dll_func::NtQuerySection);
//Obtain file name
interprocess_section_basic_information info;
unsigned long ntstatus =
pNtQuerySection(file_mapping_hnd, section_basic_information, &info, sizeof(info), 0);
size = info.section_size;
return !ntstatus;
}
Код ошибки 1 в окнах указывает ERROR_INVALID_FUNCTION
. Это означает, что эта недокументированная функция из файла ntdll.dll недоступна или недействительна для использования с file_mapping_hnd
конкретным дескриптором file_mapping_hnd
.
Возможно, вооружившись этой информацией, вы можете найти причину или спросить об этом в списке рассылки Boost