- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
由于我们不应该跨插件边界传递除普通旧数据结构 [1] 之外的任何其他内容,因此我想出了以下想法来传递对象:
我的问题是:有更好的方法吗?[编辑] 请参阅下面我的编辑,使用标准布局对象可能是更好的解决方案。
这是一个说明这个想法的玩具示例:
我想跨界传递一个 Writer :
class Writer{
Writer();
virtual void write(std::string) = 0;
~Writer(){}
};
但是,我们知道由于兼容性问题不应该直接这样做。这个想法是将 Writer 的接口(interface)公开为插件中的自由函数:
// plugin
extern "C"{
Writer* create_writer(){
return new PluginWriterImpl{};
}
void write(Writer* this_ , const char* str){
this_->write(std::string{str});
}
void delete_writer(Writer* this_){
delete this_;
}
}
并将所有这些函数调用包装在应用程序端的包装器对象中:
// app
class WriterWrapper : public Writer{
private:
Writer* the_plugin_writer; //object being wrapped
public:
WriterWrapper() : the_plugin_writer{ create_writer() }
{}
void write(std::string str) override{
write(the_plugin_writer, str.c_str() );
}
~WriterWrapper(){
delete_writer(the_plugin_writer);
}
};
这导致了很多转发功能。除了 POD 之外没有别的越界,应用程序不知道当前 Writer 的实现来自插件。
[1] 对于二进制兼容性问题。有关详细信息,您可以查看此相关的 SO 问题:c++ plugin : Is it ok to pass polymorphic objects?
[编辑] 看来我们可以通过标准布局跨越边界。如果是这样,这样的解决方案是否正确? (可以简化吗?)
我们想跨越边界传递一个 Writer :
class Writer{
Writer();
virtual void write(std::string) = 0;
~Writer(){}
};
因此我们将从插件中传递一个标准布局对象给应用程序,并将其包装在应用程序端。
// plugin.h
struct PluginWriter{
void write(const char* str);
};
-
// plugin_impl.cpp
#include "plugin.h"
extern "C"{
PluginWriter* create_writer();
void delete_writer(PluginWriter* pw);
}
void PluginWriter::write(const char* str){
// . . .
}
-
// app
#include "plugin.h"
class WriterWrapper : public Writer{
private:
PluginWriter* the_plugin_writer; //object being wrapped
public:
WriterWrapper() : the_plugin_writer{ create_writer() }
{}
void write(std::string str) override{
the_plugin_writer->write( str.c_str() );
}
~WriterWrapper(){
delete_writer(the_plugin_writer);
}
};
但是,我担心链接器会因为以下原因在编译应用程序时报错:#include plugin.h
最佳答案
在客户端和库端使用具有不同编译器(甚至语言)的 DLL 需要二进制兼容性(又名 ABI)。
无论关于标准布局或 POD,C++ 标准不保证不同编译器之间的任何二进制兼容性。在类成员的布局上没有全面的独立实现规则可以确保这一点(另见 this SO answer在数据成员的相对地址上)。
当然,幸运的是,在实践中许多不同的编译器在标准布局对象中使用相同的逻辑来填充和对齐,使用CPU 体系结构的特定最佳实践或要求(只要不使用打包或外来对齐编译器开关)。因此使用POD/标准布局相对安全(并且作为Yakk正确指出:“如果您信任 pod,则必须信任标准布局。”)
因此您的代码可能有效。其他替代方案,依靠 c++ 虚拟来避免名称混淆问题,似乎也适用于交叉编译器如 this article 中所述.出于同样的原因:在实践中,许多编译器在一个特定的操作系统+架构上使用一种公认的方法用于构建他们的 vtable。但同样,这是实践中的观察结果,并非绝对保证。
如果你想为你的库提供交叉编译一致性保证,那么你应该只依赖真正的保证,而不仅仅是通常的保证实践。在 MS-Windows 上,对象的二进制接口(interface)标准是COM。 .这是一个全面的C++ COM tutorial .它可能有点老了,但没有其他人有这么多的插图可以理解。
COM 方法当然比您的代码段更重。但这是交叉编译器的成本,甚至是它提供的跨语言合规性保证。
关于C++ 插件 : pass object across boundary (emulating it),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28500533/
我遵循了一本名为“Sitepoint Full Stack Javascript with MEAN”的书中的教程,我刚刚完成了第 6 章,应该已经创建了一个带有“数据库”的“服务器”。数据库只不过是
在 Jquery 中,我创建两个数组,一个嵌入另一个数组,就像这样...... arrayOne = [{name:'a',value:1}, {name:'b',value:2}] var arra
这个问题在这里已经有了答案: What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wa
我被放在别人的代码上,有一个类用作其他组件的基础。当我尝试 ng serve --aot(或 build --prod)时,我得到以下信息。 @Component({ ...,
我正在测试一些代码,并使用数据创建了一个 json 文件。 问题是我在警报中收到“[object Object],[object Object]”。没有数据。 我做错了什么? 这是代码:
我想打印 [object Object],[object Object] 以明智地 "[[{ 'x': '1', 'y': '0' }, { 'x': '2', 'y': '1' }]]"; 在 ja
我有一个功能 View ,我正在尝试以特殊格式的方式输出。但我无法让列表功能正常工作。 我得到的唯一返回是[object Object][object Object] [object Object]
在使用优秀的 Sim.js 和 Three.js 库处理 WebGL 项目时,我偶然发现了下一个问题: 一路走来,它使用了 THREE.Ray 的下一个构造函数: var ray = new THRE
我正在使用 Material UI 进行多重选择。这是我的代码。 {listStates.map(col => (
我的代码使用ajax: $("#keyword").keyup(function() { var keyword = $("#keyword").val(); if (keyword.
我遇到了下一个错误,无法理解如何解决它。 Can't resolve all parameters for AuthenticationService: ([object Object], ?, [o
我正在尝试创建一个显示动态复选框的表单,至少应选中其中一个才能继续。我还需要获取一组选中的复选框。 这是组件的代码: import { Component, OnInit } from '@angul
我正在开发 NodeJs 应用程序,它是博客应用程序。我使用了快速验证器,我尝试在 UI 端使用快速闪存消息将帖子保存在数据库中之前使用闪存消息验证数据,我成功地将数据保存在数据库中,但在提交表单后消
我知道有些人问了同样的问题并得到了解答。我已经查看了所有这些,但仍然无法解决我的问题。我有一个 jquery snipet,它将值发送到处理程序,处理程序处理来自 JS 的值并将数据作为 JSON 数
我继承了一个非常草率的项目,我的任务是解释为什么它不好。我注意到他们在整个代码中都进行了这样的比较 (IQueryable).FirstOrDefault(x => x.Facility == fac
我只是在删除数组中的对象时偶然发现了这一点。 代码如下: friends = []; friends.push( { a: 'Nexus', b: 'Muffi
这两个代码片段有什么区别: object = nil; [object release] 对比 [object release]; object = nil; 哪个是最佳实践? 最佳答案 object
我应该为其他人将从中继承的第一个父对象传递哪个参数,哪个参数更有效 Object.create(Object.prototype) Object.create(Object) Object.creat
我在不同的对象上安排不同的选择器 [self performSelector:@selector(doSmth) withObject:objectA afterDelay:1]; [self per
NSLog(@"%p", &object); 和 NSLog(@"%p", object); 有什么区别? 两者似乎都打印出一个内存地址,但我不确定哪个是对象的实际内存地址。 最佳答案 这就是我喜欢的
我是一名优秀的程序员,十分优秀!