2017-02-22 38 views
0

附加現有共享存儲空間的應用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)我想訪問此共享內存

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沒有設置,所以attach()中的shmget會失敗。 handle()是私有的,所以我不能調用這個函數來設置unix_key。

是否有可能訪問共享內存而不知道它的大小/調用create()?

當我嘗試調用create()

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

一個新的共享內存將創建...

我在做什麼錯?提前致謝。

+0

有兩件事我認爲可能會導致問題。一,當你結束時你會分開記憶嗎?二,你是否使用信號量信號來防止同時多次訪問內存?和附件我不知道你可以使用的任何功能,不需要區域的大小。但是,「可能」,你可以嘗試創建另一個區域只有一個整數(或東西)來保持第一個的大小。然後用它來附加它。祝你好運 – koksalb

+0

什麼操作系統?假設你有'ipcs'實用程序,'ipcs -a'的輸出是什麼?這應該顯示您的機器上的所有SysV共享內存段。 –

+0

@koksalb當共享內存成功連接時,我們可以討論分離和信號量。但在這個狀態這沒關係.. – mvollmer

回答

1

您沒有訪問相同的共享內存段。 Qt修改你傳遞它的密鑰,結果是一個不同的密鑰,因此共享內存ID。

Per the QSharedMemory documentation

警告:QSharedMemory改變Qt的特定道路上的關鍵,除非另有說明。與非Qt應用程序的互操作是 通過首先創建一個默認共享內存與 QSharedMemory(),然後設置一個本地鍵setNativeKey()實現。 使用本地密鑰時,共享內存不受保護,因爲它不能對其多個訪問(例如無法使用lock())和 用戶定義的機制實現此類保護。

這似乎是你需要創建一個使用QSharedMemory共享內存段,設置使用setNativeKey()一個新的密鑰,然後附加到從QSharedMemory之外的內存。

+0

感謝您指出這一點。 但這並不奏效。 'setNativeKey()'分離新創建的共享內存。 'QSharedMemory shmem(key); shmem.create(SHM_DATASIZE); shmem.setNativeKey(native_key);' 所以它似乎無法訪問不是由QSharedMemory創建的共享記憶。 唯一的方法是使用QSharedMemory創建SharedMemory並從其他應用程序訪問它。這有點奇怪。 – mvollmer

+0

@mvollmer如果您可以從'QSharedMemory'部分獲取實際密鑰並將其傳遞給您的非Qt應用程序,則該應用程序應該能夠直接使用該密鑰。一旦你在Qt中創建了這個段,[你可以使用'ipcs -m'](http://man7.org/linux/man-pages/man1/ipcs.1.html)查看所有共享內存段的細節。 –