[英]Safe cross-compiler ABI in C++?
In the cpp core guidelines, there is a (partially incomplete) statement : 在cpp核心指南中,有一个(部分不完整) 声明 :
I.26: If you want a cross-compiler ABI, use a C-style subset I.26:如果你想要一个交叉编译器ABI,请使用C风格的子集
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. 您可以使用一些精心挑选的更高级别的C ++类型来精心设计界面。 See ???. 见???。
A good example of a cross-compiler ABI would be a plugin system. 交叉编译器ABI的一个很好的例子是插件系统。 Let's say I want this to be as C++-friendly as possible. 假设我希望这可以像C ++一样友好。
The interface: 界面:
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);
A plugin implementation (compiled with compiler#1) might look like: 插件实现(使用编译器#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;
}
The application implementation (compiled with compiler#2) would contain something like: 应用程序实现(使用编译器#2编译)将包含以下内容:
handle->pluginMain(&createCb, &destroyCb);
Plugin* plugin = createCb();
plugin->doWork();
destroyCb(plugin);
Questions : 问题 :
Plugin
in a cross-compiler environment? 在交叉编译环境中使用Plugin
这样的类是否安全? (will it be represented the same in memory?) (它会在内存中表示相同吗?) Plugin::Type
enum affect how the Plugin class is represented? 将扩展Plugin::Type
枚举会影响插件类的表示方式吗? Update : 更新 :
In the "API design for C++" book by Martin Reddy, chapter 12, the exact scenario of using plugin interfaces seems to be specified: 在Martin Reddy的第12章“API设计for C ++”一书中,似乎指出了使用插件接口的确切场景:
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. 实现抽象基类的虚方法可以使插件与ABI问题隔离,因为虚方法调用通常表示为类的vtable的索引。 Theoretically, the vtable format can differ between compilers, but in practice this tends not to happen. 从理论上讲,vtable格式在编译器之间可能有所不同,但实际上这种情况往往不会发生。
From this, I understand that using abstract classes is generally safe between compilers, but definitely not guaranteed by the standard. 据此,我理解在编译器之间使用抽象类通常是安全的,但绝对不能通过标准来保证。
I opened an issue on Github to get examples of such exceptions and Herb Sutter's answer was: 我在Github上打开了一个问题来获取这些异常的例子,而Herb Sutter的答案是:
Editors call: We don't have a reference to point to, so we agree we should just remove the Exception. 编辑致电:我们没有指向的参考,所以我们同意我们应该删除异常。 Thanks! 谢谢!
This Exception paragraph has now been removed from the guildelines. 此例外段现已从guildelines中删除 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.