2017-02-22 28 views
0

で、既存の共有メモリを取り付け1(Cコード)イムこのような共有メモリを作成する:私は、この共有メモリアプリケーションではQSharedMemory

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; 
} 
にアクセスするアプリケーション2(QT)で
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); 

を "16858191" "を/ tmp/qipc_sharedmemory_24384b85e5d54b23bd4f84f14de71b10d4801666":

に失敗しました "が存在しないQSharedMemory ::添付する(たshmget)" を添付します210

だから私は、次の

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()はprivateなので、この関数を呼び出してunix_keyを設定することはできません。

サイズを知らずに共有メモリにアクセスすることは可能ですか/ create()を呼び出すのですか?

私が作成呼び出そう()

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

新しい共有メモリが作成されます...

は私が間違って何をしているのですか?前もって感謝します。

+0

問題が発生すると思われる2つのことがあります。 1つ、あなたはそれで終わったときにメモリを取り外すのですか? 2つのセマフォー信号を同時に使用して、メモリーへの多重アクセスを防止しますか?あなたが使用することができる機能を知っていない添付のために、その領域のサイズを必要としません。しかし、 "多分"あなたは、最初のもののサイズを保持するためにただ1つの整数(または何か)を持つ別の領域を作成しようとすることができます。その後、それを取り付けて使用してください。幸運 – koksalb

+0

どのようなOSですか?あなたが '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)を使ってすべての共有メモリセグメントの詳細を表示できます。 –

関連する問題