1 如何把对象存到共享内存?
placement new就可以,先申请一块共享内存,然后把对象placement new到对应的位置。
#include <string.h>
#include <memory>
#include <sys/shm.h>
#include <stdio.h>
#include <unistd.h>
class Test
{
public:
Test() = default;
~Test() = default;
virtual void Func() {
printf("a = %d\n", a);
}
Test& operator++()
{
this->a++;
printf("operator++ ######\n");
return *this;
}
Test operator++(int)
{
Test temp(*this);
a++;
return temp;
}
int a = 0;
};
class TestApp: public Test
{
public:
void Func() {
printf("TestApp a = %d\n", a);
}
};
int main()
{
int shmid = shmget(10000, 4096, IPC_CREAT|0664);
void* ptr = shmat(shmid, NULL, 0);
Test *t = new (ptr) TestApp(); //new对象
while (true) {
t->a++;
t->Func();
printf("a value %d\n", t->a);
sleep(1);
}
}
2 如何恢复对象?
2.1 如果只是普通的对象,拿到共享内存地址强制转型就可以了
Test *t = (TestApp*)ptr;
但是因为这个类有虚函数,虚函数表编译后是个固定的数据存放在数据区,程序每次运行的时候,会有一个动态绑定的过程,就是说这个虚函数表的首地址(虚拟地址)每次执行都不一样,之前共享内存里面存储的是上一次运行的,无法用来寻址虚函数了?那怎么解决呢?
#include <string.h>
#include <memory>
#include <sys/shm.h>
#include <stdio.h>
#include <unistd.h>
class Test
{
public:
Test() = default;
~Test() = default;
virtual void Func() {
printf("a = %d\n", a);
}
Test& operator++()
{
this->a++;
printf("operator++ ######\n");
return *this;
}
Test operator++(int)
{
Test temp(*this);
a++;
return temp;
}
int a = 0;
};
class TestApp: public Test
{
public:
void Func() {
printf("TestApp a = %d\n", a);
}
};
int main()
{
int shmid = shmget(10000, 4096, IPC_CREAT|0664);
void* ptr = shmat(shmid, NULL, 0);
Test *tt = new TestApp();//先new一个对象,
Test *t = (Test*)ptr; //找到共享内存对象
memcpy(t, tt, 8); //把new出来对象的vtab首地址copy过来
while (true) {
t->a++;
t->Func();
printf("a value %d\n", t->a);
sleep(1);
}
}
new新的对象->找到共享内存对象->把new对象的起始8字节(vtab首地址)copy过来