- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经使用 C++ 抽象类定义了一个接口(interface)。我想为我的项目的不同变体多次实例化它(变体可以是硬件变体或操作系统变体)。我的目标是为每个变体创建共享库,并为给定项目使用正确的库,而无需重新编译任何东西。
我为了检索给定变体所需的实例,我使用的是公共(public)函数。在每个变体的 cpp 文件中,我定义了一个函数来返回该变体的实例。在主代码中,我正在对该函数进行外部声明。我打算使用返回的对象调用接口(interface)的方法。
// Interface.hpp
class Interface {
public:
virtual void routine() = 0;
};
// variantA.cpp
class variantA : public Interface {
public:
void routine() {
printf( "We are in variantA\n" );
}
} variant;
Interface& getVariant() {
return variant;
}
// variantB.cpp
class variantB : public Interface {
public:
void routine() {
printf( "We are in variantB\n" );
}
} variant;
Interface& getVariant() {
return variant;
}
// main.cpp
#include "Interface.hpp"
extern Interface& getVariant();
int main() {
Interface& interface = getVariant();
interface.routine();
}
// build.sh
g++ -c -fPIC -O0 variantA.cpp
g++ -c -fPIC -O0 variantB.cpp
g++ variantA.o -shared -o libvariantA.so
g++ variantB.o -shared -o libvariantB.so
ln -s libvariantA.so libvariant.so
g++ -L. -lvariant main.cpp -o main
主要问题:我的方法理论上是否正确?这样做是个好主意吗?或者,这种方法有什么明显的缺陷吗?如果是这样,谁能给我推荐一个更好的方法?
第二个问题:我可能可以通过一些试验自己弄清楚。但我仍然发布这个,因为这可能会使该方法无法使用。问题是编译错误:
In function `main':
main.cpp:(.text+0x9): undefined reference to `getVariant()'
collect2: error: ld returned 1 exit status
最佳答案
首先不要在使用前声明,它属于接口(interface) header ,这正是 header 的用武之地。
但我担心我们得到了一个 XY problem这里:
I want to instantiate it multiple times for different variants of my project (variants can be hardware variants or OS variants). My goal is to create shared libraries for each variant and use the right one for a given project without having to re-compile anything.
这是不可能的:您通常无法为硬件或操作系统变体 a 编译 libvarianta,而为硬件或操作系统变体 b 编译 libvariantb,并在一个同时链接到 a 和 b 的程序中一起使用它们。
问题在于,您通常每次都必须重新编译是有原因的:不同的硬件和不同的操作系统通常需要不同的机器代码。即使是 printf
调用也会针对不同的编译器或操作系统转换为不同的机器代码。这就是 C++ 标准和引用与运行时和实现的含义。
此外,您通常甚至无法调用该函数,因为在使用共享链接时您会遇到 ABI 的问题。 (不是 API),这也意味着即使对于相同体系结构的相同 Microsoft 编译器版本,您也必须编译一次用于调试,一次用于发布版本(unless further precaution are followed)。
大多数库甚至通过使用预处理器在不同平台上编译不同的高级代码。
因此,您仍然必须为您的库和库的使用者编译所有需要的不同版本,这将需要复杂的逻辑才能知道要加载哪个二进制文件。换句话说:您将不得不找到一个共享库二进制文件,如果您只是将它们简单地编译在一起,您就会得到这个二进制文件。因此,简单地静态链接它并使用一个 API 会更容易,不需要抽象类或接口(interface),至少在运行时是明智的。您可能需要在编译时做不同的事情,因为您可能没有可移植的方式来做事情。然后您可以使用预处理器宏或 compile time polymorphism .这符合 John3136 给您的建议。
所以不,共享链接不会解决问题,即据我了解您的问题,实现您尝试做的事情。它只会产生更复杂的问题。共享链接不是可移植的,甚至不是纯标准 C++ 的东西。然而,不同的操作系统如何尝试实现 ABI 稳定性(如 Windows 上的 COM 对象)有一些技巧,但如果您的代码需要针对不同的硬件或运行时,这仍然无法解决问题。
关于c++ - 使用共享库进行变体处理是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58386610/
我正在更新一个旧的经典 ASP 站点并且我需要存储密码,因此考虑到经典 ASP 的局限性,我对如何处理这个问题自然有点过于谨慎。 我同时使用盐和胡椒(胡椒是存储在服务器上而不是数据库中的常量),我只是
我已经设置了我的数据库来记录每次失败的登录尝试。我以为我会将失败尝试的次数乘以 0.05 秒之类的。就像是: time_nanosleep(0, (50000000 * $fa
我想测量 1GB LAN 上消息代理的广播消息延迟。 消息以 pub sub 方式传输,一个发布者,多个消费者。生产者使用系统时钟(C# 中的 DateTime.Now)为每条消息加上时间戳,消费者通
我正在尝试学习代码契约并了解它们的用处。 我有一个 WPF 应用程序,因此很多代码注定要在 UI 线程上独占运行。相当多的实用程序类期望仅从 UI 线程调用。 在我的代码中加入这些是个好主意吗?为什么
我加入了一家小公司,该公司主要销售一种网络应用程序。 Web 应用程序中的数据非常敏感,以至于所有数据都经过字段级加密。应用程序使用 ASP.NET Web API 2(C#) 编写,前端为 html
对于我网站的后端,只有少数人可见,我有一个系统,通过 ajax 与 php 进行通信,如下所示: function ajax(url, opts) { var progress = false
我们有相当大的文档集,我们希望我们的用户能够查看和过滤这些文档。为了加快速度,我们只向客户发送有限数量的文件。但是,由于我们确实需要客户端能够过滤文档,因此我们需要一种方法来发送他们可以过滤的键和值。
我从 14 岁起就开始阅读游戏引擎书籍(那时候我什么都不懂:P)几年后,我想开始为我的游戏引擎编写数学基础。我一直在思考如何设计这个“图书馆”。 (我的意思是“有组织的文件集”)每隔几年就会出现新的
我们正在使用 Rails 为餐厅构建 SaaS 后端。我们直接与 POS 集成,因此每个 POS 不断发送我们存储的客户订单以供以后处理。我们在大约 1,000 个地点进行了这种 POS 集成,每月向
我正在设计一个系统,但我认为让最终用户能够删除数据库中的条目并不是一个好主意。我是这么认为的,因为通常最终用户一旦获得管理员权限,最终可能会在数据库中弄得一团糟,然后求助于我来修复它。 当然,如果他们
我正在考虑使用 RESTful Web 服务构建应用程序。我的想法是将应用程序的 RESTful(json 等)部分构建为独立的,然后将前端(例如 html/css/js/等)构建为该服务的客户端,虽
我有一种情况,我要保留对需要持久化的 ivar 的引用。在一个对象中,我有一个指向另一个对象中的 ivars 的指针数组,这些指针在程序的整个生命周期中都被使用。换句话说,我不只是传递一个引用来检索一
有没有prototype没有任何 DOM/ajax 部件的 fork?我真的更喜欢 jQuery,并且不想背负额外的包袱。到目前为止,我一直在使用优秀的 JS.Class库,它甚至不触及内置类原型(p
我正在从事的项目需要我编写大量重复代码。例如,如果我想在我的代码中加载一个名为“logo.png”的图像文件,我会这样写:位图标志图片; ... // Init logoImage = load("l
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 3年前关闭。 Improve t
我有一个小型网站,大约有 5-10 名管理员。我已将其设置为监视每个管理员正在做什么(添加项目、删除项目等)。我在我们的管理面板中有一个列表,显示了集体管理部门之前执行的 10 项事件。今天,我决定每
我看到将 PostgeSQL 数据库转储到一个大 SQL 文件中,然后提交并推送到远程 Git 存储库的方式可能是一个了不起的备份解决方案:我获得了所有版本的历史记录、散列、安全传输、单向(真的很难通
我正在开发一个需要本地化和国际化的 Web 应用程序。我突然想到我可以使用依赖注入(inject)框架来做到这一点。假设我声明了一个接口(interface) ILocalResources(在本示例
更新 :正如我所料,社区针对这个问题给出的合理建议是“衡量并观察”。 chibacity posted an answer一些非常好的测试为我做了这件事;同时,我自己写了一个测试;我看到的性能差异实际
我想知道使用 new 运算符创建对象但不将返回的对象分配给任何变量是否是个好主意。本质上,我只是在同一行中调用这些方法。例如: new Object().ToString(); 好吧,我知道上面的行不
我是一名优秀的程序员,十分优秀!