1

In Application 1(C Code) im creating a shared memory like this:

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);

In Application 2(QT) i want to access this 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;
}

attach failed "QSharedMemory::attach (shmget): doesn't exist" "16858191" "/tmp/qipc_sharedmemory_24384b85e5d54b23bd4f84f14de71b10d4801666"

So i've tried the following

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;
}

attach failed "QSharedMemory::attach (shmget): doesn't exist" "" "/tmp/shmem_prot"

I've taken a look at the source of qsharedmemory_unix.cpp

I think the Problem is that unix_key is not set, so that shmget in attach() will fail. handle() is private, so i cant call this function to set the unix_key.

Is it possible to access the shared memory without knowing the size of it / calling create()?

When i try to call create()

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

a new shared memory will created...

What am I doing wrong? Thanks in advance.

Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
mvollmer
  • 187
  • 2
  • 11
  • there are 2 things i think might cause problems. One, do you detach the memory when you are over with it? two, do you use semaphore signals to prevent multiple access to the memory at the same time? and for the attaching i dont know any function you can use that doesnt require the size of the area. But "maybe" you can try to create another area with only one integer(or something) to hold the size of the first one. And use it to attach it afterwards. good luck – koksalb Feb 22 '17 at 12:05
  • What OS? Assuming you have the `ipcs` utility, what's the output from `ipcs -a`? That should show all SysV shared memory segments on your machine. – Andrew Henle Feb 22 '17 at 12:36
  • @koksalb We can talk about detaching and semaphores when the shared memory was successfully attached. But at this state this doesnt matter.. – mvollmer Feb 23 '17 at 06:39
  • @AndrewHenle I'm using Linux Mint. Im already using ipcs. `0x01013c3f 1048586 mvollmer 600 23720 1 0x13013c51 1507340 mvollmer 600 23720 1 ` 1048586 created by Application 1 and 1507340 is created by QT. – mvollmer Feb 23 '17 at 06:45

1 Answers1

3

You're not accessing the same shared memory segment. Qt modifies the key you pass it, and the result is a different key and therefore shared memory id.

Per the QSharedMemory documentation:

Warning: QSharedMemory changes the key in a Qt-specific way, unless otherwise specified. Interoperation with non-Qt applications is achieved by first creating a default shared memory with QSharedMemory() and then setting a native key with setNativeKey(). When using native keys, shared memory is not protected against multiple accesses on it (for example, unable to lock()) and a user-defined mechanism should be used to achieve such protection.

It would seem that you need to create the shared memory segment using QSharedMemory, set a new key using setNativeKey(), then attach to that memory from outside of QSharedMemory.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • 1
    Thanks for pointing this out. But this doesnt work. `setNativeKey()` is detaching the new created shared memory. `QSharedMemory shmem(key); shmem.create(SHM_DATASIZE); shmem.setNativeKey(native_key);` So it seems that its not possible to access shared memorys which were not created by QSharedMemory. The only way is to create a SharedMemory with QSharedMemory and access it from an other application. This is kinda weird. – mvollmer Feb 23 '17 at 07:38
  • @mvollmer If you can get the actual key from the `QSharedMemory` segment and pass that to your non-Qt application, that application should be able to use that key directly. Once you create the segment in Qt, [you can use `ipcs -m`](http://man7.org/linux/man-pages/man1/ipcs.1.html) to view details on all shared memory segments. – Andrew Henle Feb 23 '17 at 10:44