c++ - 如何正确地将带有 vtable 的类实例写入和读取到 QSharedMemory 中?

标签 c++ qt shared-memory virtual-table

我有一个从接口(interface)派生的类

class Interface {
public:
  virtual void foo() = 0;
};

class Implementer : public Interface {
public:
  void foo() override { std::cout << "Hello world" << std::endl; }
private:
  int __some_int_member;
};

现在我想编写一个程序,它将在所有应用程序实例中获取相同的 Implementer 类实例。我按照建议的例子 here (第二个),但在那个例子中,只使用了一个字节。

int main(int argc, char **argv)
{
  QCoreApplication app(argc, argv);
  Implementer *impl = nullptr;
  QSystemSemaphore accessor("app_accessor", 1);
  accessor.acquire();
#ifndef QT_OS_WIN
  QSharedMemory mem_fix("my_class");
  if(mem_fix.attach())
  {
    mem_fix.detach();
  }
#endif
  QSharedMemory mem("my_class");
  if(!mem.attach())
  {
    mem.create(sizeof(Implementer));
    new(mem.data()) Implementer();
  }
  impl = (Implementer*)mem.data();
  accessor.release();

  impl->foo();
  return app.exec();
}

第一个实例工作正常。但是它在 impl->foo() 上的第二个崩溃。

我认为原因是从 void*Implementer* 的错误转换。但我不知道如何正确地做到这一点。

有什么建议吗?

编辑

我意识到,Segmentation fault 导致的崩溃是继承的结果,因为没有基类一切正常。

编辑2

经过一些调试、内存转储和一些注释后,我意识到,问题是在运行时程序的第一个实例在其堆栈中创建了 vtable 并将 vptr 到它的 vtable。第二个实例获得相同的 vptr,不幸的是,它指向一些随机内存(可能已分配或未分配)。

最佳答案

具有虚函数的基类需要一个vtableThe memory location of the vtable or even the existence of it is implementation-dependent ,因此当您尝试通过 vtable 访问函数时会出现异常。

您可以做的是将数据和逻辑分开。定义一个只有数据的新类,共享它并在其上应用一些功能。

但是,由于您计划将 QMap 作为数据共享,因此您似乎还会遇到更多问题。它可能将其数据存储在堆上并且不提供内存分配器接口(interface)(至少我看不到)。这意味着您将无法控制它在何处分配数据。如果您确定需要映射结构,则可以使用 std::map 并为使用您创建的共享内存的映射提供您自己的内存分配器。我刚刚在 google 中编写了 c++ std map custom memory allocator,它显示了一些解决方案。还有this SO 中的问题可能对您有帮助。

关于c++ - 如何正确地将带有 vtable 的类实例写入和读取到 QSharedMemory 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57298775/

相关文章:

C++ 排序真假数组

c++ - Qt:子对象可以在其父对象中组合吗?

c++ - 如何使用 QDataStream::readBytes()

docker - 跨 Docker 容器共享内存 : '--ipc=host' vs. '--ipc=shareable'

c - 如果我使用 select() 服务器编写一个对等 2 个对等应用程序而不使用 fork()、线程、共享内存、信号量,这样可以吗?

sqlite vs 共享内存应用程序 vs ipc vs?

c++ - 什么 C++ 转换运算符等同于 (MyStructType){1,2,3}?

c++ - cv::gpu::HoughLines 无法正常工作

c++ - 如何从 C++/Qt 调用 Objective-C 代码(特别是来自 Mac 系统库的代码)?

c# - Spy++ 无法到达 Qt 应用程序中的按钮