【问题标题】:Finding a way to use PIMPL with external constant definitions for the size of an array inside the implementation寻找一种方法来使用 PIMPL 与实现内部数组大小的外部常量定义
【发布时间】:2021-02-17 16:37:55
【问题描述】:

我们有以下情况:我们使用的处理器在其 RAM 中定义了部分,必须由使用 PIMPL 原则的特殊实现使用。例如,私有实现看起来像这样:

Impl( )
{
public:
  void doSomething()
  {
    for( uint32_t i = 0; i < DATA_SIZE; ++i )
    {
      // do stuff with buf[i]
    }
  }
private:
  
  static uint8_t  buf[DATA_SIZE] __attribute__ ((section("data_buffer"), aligned (8)));
};

如您所见,此处未定义 DATA_SIZE。这里的重点是,我们可以在同一供应商的不同处理器上使用 Impl 中的处理器供应商提供的函数,并使用不同的链接脚本定义“data_buffer”部分。这是可能的,因为使用的底层系统为同一家族的不同处理器提供了相同的功能。 但它必须是一个 PIMPL 来保证如果我更换到另一个供应商的不同处理器,我们可以为另一个供应商使用另一个 Impl。 因此,可能有人正在使用具有不同 DATA_SIZE 的部分,因为他在他的项目中以不同的方式定义了他的部分(即使在同一个处理器上)。 初始化和一切当然将通过构造函数等完成。

但是是否可以使 DATA_SIZE 可设置而不直接在 Impl-File 中定义?

据我所知,PIMPL 的目标是编译它并定义一个 ABI,这对我来说意味着编译后的文件在链接后不能改变大小。我的想法对吗? (对我来说,现在只是快速更改实现,并且永远不要接触上层使用 PIMPL 的软件部分,但将来我们将使用“pimpl-library”,我们只想更改编译后的 Impl-文件。)

我想阻止使用派生的基类/接口类来完全隐藏对开发人员的实现,并且不传递派生类的任何引用或指针,因为这需要在上层进行软件更改层。

感谢您的意见。

【问题讨论】:

  • 您考虑过只使用#define 吗?

标签: c++ linker pimpl-idiom pimpl


【解决方案1】:

但是是否可以使 DATA_SIZE 可设置而不直接在 Impl-File 中定义?

非静态成员数组的大小必须在类定义中设置。

您可以使用预处理器包含来自其他地方的值,因此在这个意义上它不必是“在文件中”,但无论大小是多少,它必须匹配所有 TU 并更改大小只在私有实现内部而不修改接口的客户端是不可能的..


请注意,只要将数组至少定义为指针的大小和对齐方式,那么您就可以使用间接实现私有实现中的任何数据 - 通过存储指针并在动态存储中创建具体对象。

【讨论】:

  • 我将 buf 切换为静态,否则它无论如何都不会编译,因为属性“section”不能在那里使用。只是忘了正确地写下来。但是数组在使用section-attribute时不需要定义它的大小吗?我可以在不同的文件中定义这个数组并将指向它的指针传递给 impl 类吗?所以我们至少可以对数组有不同的“impls”,然后将它们包含在 Impl 中。然后,构建系统将选择正确的文件包含在其中,这意味着使用那里定义的 DATA_SIZE 链接到数组。
  • @NetoBF 我不知道“部分属性”。这是非标准的。看看提供语言扩展的任何编译器的手册是怎么说的。
  • @NetoBF 不清楚您所说的“impl-class”是什么意思。 Impl 是“实现”的缩写,在 PIMPL 中保持私有。那么,您是在谈论名为Impl 的类而不是实现,还是不是名为Impl 的类的实现? for the arrays at least ...如果将数组定义为静态成员,那么数组只有一个,不多。
  • 抱歉给您带来了困惑。部分是 ARM 的特殊部分:developer.arm.com/documentation/dui0491/f/… “impl-class”是我示例中的 Impl。所以这是私有实现,是的。我只是没有在这里写外部类,我会在问题中澄清它。我为我使用了多个数组,我只是在这里放置了一个作为示例。
  • 所以你用指针让我想到了这个想法。如果我在 Impl.cpp 旁边放置单独的文件夹,比如说“proc1”、“proc2”.. 等等,每个人都包含相同命名的头文件,例如“sections.hpp”,然后包含DATA_SIZE 和静态数组。然后 Impl.cpp 将包含标题“sections.hpp”并且不直接使用数组而是指向它的指针。因此,我可以通过我的构建系统定义在链接时要包含其包含的“sections.hpp”标题的文件夹。这应该不会破坏 PIMPL,对吧?
猜你喜欢
  • 2023-03-09
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
相关资源
最近更新 更多