PDA

View Full Version : qsharedmemory between Qt and c program on linux plateform



marwan
9th May 2012, 17:27
Hi everybody
I 'm beginner in Qt, I have a problem to read a shared memory segment generated by c program on qt application using nativekey().
if someone have any idea or solution please help me
my c prog generate a data on shared memory with this key-id 0x00313233
and this is my source :


QSharedMemory shm("123");
if (shm.isAttached())
shm.detach();
if (!shm.attach(QSharedMemory::ReadWrite)) {
// Shared memory n'est pas crée donc création
if (!shm.create(1024, QSharedMemory::ReadWrite)) {
QSharedMemory::SharedMemoryError err = shm.error();
qDebug()<< err <<"Erreur lors de création de shared memory";
}
else {
qDebug()<< "memory attached successfully";
qDebug()<< "memory created successfully";
qDebug()<< "memory keyid"<<shm.key().toAscii().toHex();

if(shm.lock()){
qDebug()<<"Memory locked successefully";
QByteArray s = QByteArray((char*) shm.constData(), shm.size());
QString message = QString::fromUtf8(s.constData());
qDebug() << message;

if(shm.unlock()){
qDebug()<< "Memory unlocked successefully";
if(shm.detach())
qDebug()<<"Memory detached successefully";
else qDebug()<<"Memory detached failed"<< shm.error();
}
else qDebug()<< "Memory unlock failed"<< shm.error();
}
else qDebug()<<"Memory lock failed"<< shm.error();
}
}


QTextEdit *textedit= new QTextEdit(s);
QHBoxLayout *layout = new QHBoxLayout( &mainwindow );

amleto
9th May 2012, 22:09
[/b]] tags please

"this key-id 0x00313233
and this is my source :

QSharedMemory shm("123");"

123 doesnt look very much like 0x00313233. What do you think about that?


"...using nativekey()."
Where are you using nativekey()? I don't see it anywhere...

marwan
9th May 2012, 22:36
thank you for your interest
first, I use Qsharedmemory shm("123") because of casting "123" to hex is equal to 0x00313233
second, for the nativekey ,i just asked how can I use it in my application to assign the shared memory segment created by c program

thank you.

amleto
9th May 2012, 23:31
you must have qt 4.8 or later. you should NOT pass a key into ctor.

I'm not sure if your casting of hex to string is right or not.

wysota
10th May 2012, 00:25
Can we see the exact code you use to create the shared memory segment in your C program?

marwan
10th May 2012, 07:22
I use qt 4.8.1 that offer the possibility to inter-process with other platform
for the c program, i haven't problem to run it and allocate shared memory,it is so simple,it create a segment on the defined key and write something on it
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHM_SIZE 1024 /* make it a 1K shared memory segment */

int main(int argc, char *argv[])
{
key_t key;
int shmid;
char *data;
int mode;

if (argc > 2) {
fprintf(stderr, "usage: shmdemo [data_to_write]\n");
exit(1);
}

/* make the key: */
/*if ((key = ftok("shm.c", 'R')) == -1) {
perror("ftok");
exit(1);
}*/

// static atribute of key

key=0x00313233;

/* connect to (and possibly create) the segment: */
if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
perror("shmget");
exit(1);
}

/* attach to the segment to get a pointer to it: */
data = shmat(shmid, (void *)0, 0);
if (data == (char *)(-1)) {
perror("shmat");
exit(1);
}

/* read or modify the segment, based on the command line: */
if (argc == 2) {
printf("writing to segment: \"%s\"\n", argv[1]);
strncpy(data, argv[1], SHM_SIZE);
} else
printf("segment contains: \"%s\"\n", data);
printf("key ID: \"%x\"\n", key);
printf("shmid ID: \"%d\"\n", shmid);

/* detach from the segment: */
/*if (shmdt(data) == -1) {
perror("shmdt");
exit(1);
}*/

return 0;
}

and this is the output:
mar@mar-laptop:~/omapDev/sharedmem$ ./shm CAFEFADE
writing to segment: "CAFEFADE"
key ID: "313233"
shmid ID: "1736737"

thank you.

wysota
10th May 2012, 09:39
Why do you think "key_t" is an equivalent of "char*"? At least on my system it is an int (through the chain of typedefs key_t -> __KEY_T_TYPE -> __S32_TYPE -> int), not a char*.

marwan
10th May 2012, 10:50
@Wysota
because on qt, the key id must be qstring to pass on constructor of Qsharedmemory.
please if you have another solution , I get it.

wysota
10th May 2012, 10:59
@Wysota
because on qt, the key id must be qstring to pass on constructor of Qsharedmemory.
That doesn't mean that if another API (apparently not directly compatible with this one as key_t is obviously a handler and not a key itself) is using an integer, you can pass a hexadecimal equivalent of the key and expect them to cooperate. A direct equivalent of Qt API is shm_open and family.

marwan
14th May 2012, 07:52
Thank you wysota for help
but, i want to know if i should use the Qsahredmemory functions(create(),setkey(),attach(),lock()) or shm functions (chmget(),shmat()...); personnaly i prefer use the first choice because it's more simple and acces management to the memory respected.

wysota
14th May 2012, 08:42
It doesn't matter as long as you interchange APIs that are compatible. What Qt does is it takes a file path you pass as the key, calls ftok() on it (with 'Q' as the proj_id parameter) and then uses the result with shmget(). Your code bypasses the first two steps thus you don't have a valid key.