2017-02-22 43 views
0

В Application 1 (C-код) им создать общую память, как это:Присоединить существующий общий объем памяти с QSharedMemory

char * key_path = "/tmp/shmem"; 

int file = open(key_path, O_CREAT | O_RDWR | O_APPEND, 0755); 
close(file); 
key_t key = ftok(key_path, 1); 

shmid = shmget (key, SHM_DATASIZE , IPC_CREAT | SHM_R | SHM_W); 
shmdata = shmat(shmid, NULL, 0);shmid); 

В заявке 2 (QT) я хочу, чтобы получить доступ к этой SharedMemory

const char* native_key = "/tmp/shmem"; 

key_t ft_key = ftok(native_key, 1); 
key = QString::number(ft_key); 

QSharedMemory shmem(key); 
if(!shmem.attach()) { 
    qDebug() << "attach failed" << shmem.errorString() << shmem.key() << shmem.nativeKey() << endl; 
} 

подключением не удалось "QSharedMemory :: присоединять (shmget): не существует", "16858191" "/ TMP/qipc_sharedmemory_24384b85e5d54b23bd4f84f14de71b10d4801666"

Так я попробовал следующее

const char* native_key = "/tmp/shmem"; 

key_t ft_key = ftok(native_key, 1); 
key = QString::number(ft_key); 

QSharedMemory shmem(key); 
shmem.setNativeKey(native_key); 
if(!shmem.attach()) { 
    qDebug() << "attach failed" << shmem.errorString() << shmem.key() << shmem.nativeKey() << endl; 
} 

подключением не удалось "QSharedMemory :: присоединять (shmget): не существует" "" "/ TMP/shmem_prot"

Я взглянул на источник qsharedmemory_unix.cpp

Я думаю, проблема заключается в том, что unix_key не установлен, поэтому shmget в attach() завершится с ошибкой. handle() является закрытым, поэтому я не могу вызвать эту функцию, чтобы установить unix_key.

Возможно ли получить доступ к общей памяти, не зная ее размера/вызова create()?

Когда я пытаюсь вызвать создать()

QSharedMemory shmem(key); 
shmem.create(SHM_DATASIZE); 

будет создана новая общая память ...

Что я делаю неправильно? Заранее спасибо.

+0

Есть 2 вещи, которые, я думаю, могут вызвать проблемы. Во-первых, вы отделите память, когда закончите с ней? два, вы используете сигналы семафора для одновременного предотвращения множественного доступа к памяти? и для прикрепления я не знаю никакой функции, которую вы можете использовать, которая не требует размера области.Но «возможно» вы можете попытаться создать другую область с одним целым числом (или чем-то), чтобы удержать размер первого. И используйте его, чтобы прикрепить его впоследствии. удачи – koksalb

+0

Какая ОС? Предполагая, что у вас есть утилита 'ipcs', каков вывод из' ipcs -a'? Это должно показать все сегменты разделяемой памяти SysV на вашем компьютере. –

+0

@koksalb Мы можем поговорить об отсоединении и семафорах, когда общая память была успешно присоединена. Но в этом состоянии это не имеет значения. – mvollmer

ответ

1

Вы не получаете доступ к одному и тому же сегменту разделяемой памяти. Qt изменяет ключ, который вы передаете, и результатом является другой ключ и, следовательно, идентификатор разделяемой памяти.

Per the QSharedMemory documentation:

Предупреждение: QSharedMemory меняет ключ в Qt-специфическим образом, если не указано иное. Взаимодействие с приложениями, отличными от Qt, составляет , достигнув первого создания разделяемой памяти по умолчанию с QSharedMemory(), а затем установив собственный ключ с setNativeKey(). При использовании встроенных ключей общая память не защищена от множественных доступов на ней (например, не может быть lock()), и для достижения такой защиты должен использоваться пользовательский механизм .

Казалось бы, что вам нужно создать разделяемый сегмент памяти с помощью QSharedMemory, установить новый ключ, используя setNativeKey(), а затем приложить к этой памяти из-за пределов QSharedMemory.

+0

Спасибо, что указали это. Но это не работает. 'setNativeKey()' отделяет новую созданную общую память. 'QSharedMemory shmem (ключ); shmem.create (SHM_DATASIZE); shmem.setNativeKey (native_key); ' Похоже, что невозможно получить доступ к разделяемой памяти, которые не были созданы QSharedMemory. Единственный способ создать SharedMemory с QSharedMemory и получить доступ к нему из другого приложения. Это странно. – mvollmer

+0

@mvollmer Если вы можете получить фактический ключ из сегмента 'QSharedMemory' и передать его в приложение, отличное от Qt, это приложение должно иметь возможность напрямую использовать этот ключ. После создания сегмента в Qt [вы можете использовать 'ipcs -m'] (http://man7.org/linux/man-pages/man1/ipcs.1.html), чтобы просмотреть сведения обо всех сегментах разделяемой памяти. –

 Смежные вопросы

  • Нет связанных вопросов^_^