Attach existing Shared Memory with QSharedMemory

3.2k views Asked by At

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.

1

There are 1 answers

2
Andrew Henle On BEST ANSWER

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.