c++ - C++ 中的安全交叉编译器 ABI?

标签 c++

在cpp核心指南中,有一个(部分不完整)statement :

I.26: If you want a cross-compiler ABI, use a C-style subset

Reason

Different compilers implement different binary layouts for classes, exception handling, function names, and other implementation details.

Exception

You can carefully craft an interface using a few carefully selected higher-level C++ types. See ???.

交叉编译器 ABI 的一个很好的例子是插件系统。假设我希望它尽可能对 C++ 友好。

界面:

class Plugin
{
public:
    virtual ~Plugin() {}

    enum class Type {A, B, C};
    virtual Plugin::Type getType() const = 0;

    virtual void doWork() = 0;
};

// C-style for the main plugin entry function
typedef Plugin* (*PluginCreateCallback)();
typedef void (*PluginDestroyCallback)(Plugin*);
extern "C" void pluginMain(PluginCreateCallback* createCb, PluginDestroyCallback* destroyCb);

插件实现(使用 compiler#1 编译)可能如下所示:

class MyPlugin: public Plugin
{
    Plugin::Type getType() const override {return Plugin::Type::A;}
    void doWork() {...}
};

Plugin* myCreateCb()
{
    return new MyPlugin();
}

void myDestroyCb(Plugin* plugin)
{
    delete plugin;
}

extern "C" void pluginMain(PluginCreateCallback* createCb, PluginDestroyCallback* destroyCb)
{
    *createCb = &myCreateCb;
    *destroyCb = &myDestroyCb;
}

应用程序实现(使用 compiler#2 编译)将包含如下内容:

handle->pluginMain(&createCb, &destroyCb);
Plugin* plugin = createCb();
plugin->doWork();
destroyCb(plugin);

问题:

  • 在交叉编译器环境中使用像Plugin 这样的类是否安全? (它会在内存中表示相同吗?)
  • 扩展 Plugin::Type 枚举会影响 Plugin 类的表示方式吗?
  • 更一般地说,那些“精心挑选的高级 C++ 类型”是什么?

更新:

在 Martin Reddy 的“API design for C++”一书中,第 12 章似乎指定了使用插件接口(interface)的确切场景:

Implementing virtual methods of an abstract base class can insulate a plugin from ABI problems because a virtual method call is usually represented as an index into a class’s vtable. Theoretically, the vtable format can differ between compilers, but in practice this tends not to happen.

由此,我了解到使用抽象类在编译器之间通常是安全的,但标准绝对不能保证。

最佳答案

我打开了一个 issue on Github获取此类异常的示例和 Herb Sutter's answer是:

Editors call: We don't have a reference to point to, so we agree we should just remove the Exception. Thanks!

这个异常(exception)段落has now been removed来自准则。

关于c++ - C++ 中的安全交叉编译器 ABI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56423854/

相关文章:

c++ - std::vector 超出范围

c++ - 通过宏定义编译标志(C++11 和优化)

c++ - 将类初始化为结构体成员

c++ - OpenCV Mat 在 push_back 时崩溃

c++ - OpenCV C++ 和 cvSmooth

c++ - 为什么 Netbeans 无法识别我的 C++ 应用程序中的 forward_list?

c++ - 观察者模式中的 Const-correct 通知程序

c++使用通过数据包接收的 key 加密文本? key 沙皇?

C++ dll函数在delphi7中的调用

c++ - 删除 std :list<User_Define> that satisfy certain conditions? 中元素的最佳方法是什么