如何在与低(更低)级接口交互时编写良好的C++代码?

3
在我的C++代码中,我必须处理用C编写的接口以及CUDA内核。我在Stackoverflow上发布了一些问题,询问如何在C++中实现这样或那样的操作。我得到了很多答案,如:“不要这样做。C++有更好的解决方案,请看一下这个或那个。”另一方面,由于与C接口或CUDA的交互,我认为我确实不得不以那种方式进行。
长话短说:我越来越意识到,C接口和低级别的东西会导致在设计代码时遵循良好的C++思想时出现困难。
那么,我现在想要什么?我正在寻找一些文献,类似于“Effective C ++”,但专门针对那些必须处理低级别方面的人。

1
你几乎总是以某种形式创建函数存根:http://en.wikipedia.org/wiki/Method_stub - Bathsheba
我有点困惑...你是想让你的接口能够被C/CUDA调用,还是想在C/CUDA代码周围建立面向对象的封装? - IdeaHat
如果有一个实际的例子,回答起来会容易得多。 - John Dibling
1
我明白问题所在。这不是关于如何解决特定问题的问题。我更多地寻找一些文献,类似于《Effective C++》,但专门针对那些必须处理低级方面的人。 - Michael
1
你可以使用每个问题的解决方案#1:添加一个间接层。 - R. Martinho Fernandes
显示剩余2条评论
1个回答

0
以下是与编写代码相关的一些概念需要记在心中:
  • 封装/数据隐藏
  • 变更传播
  • 细节/抽象化
  • 耦合/依赖关系

常见的架构是使用金字塔布局进行抽象化。最底层知道硬件的具体情况。每向上一层,则越来越远离硬件,逐渐接近应用程序。

封装和数据隐藏

这里的想法是,与单个硬件项相关的所有内容都应在其封装中。共享相同功能但位于不同地址的常见设备应从单个接口继承。例如,假设有三个位于地址0x1000、0x2000和0x3000处的USB端口,它们的使用方式相同,唯一的区别是它们的硬件寄存器位于不同的地址。因此,应该有一个USB_Interface_Base_Class,以及3个实例或3个子类。

USB类别应该只暴露基本功能。类别的使用者不关心硬件寄存器,只关心进行I/O操作。因此,详细信息对于类别的外部用户是隐藏的。

变更传播

在研究和开发过程中,硬件是易变的,可能在生产过程中发生改变。目标是减少变更的传播。例如,如果将USB接口更改为无线电接口,则硬件访问层应更改,但更改不应深入应用程序。需要更改的模块越少,就越好。

详细信息和抽象

每个远离硬件的层次应比前一个较低的层次具有更高级别的抽象。

例如,最高级别的执行操作为:`cout << "Hello\n"`; 下一层可以缓冲数据并调用“驱动程序”。 驱动程序表示它想要与字符输出设备交互。默认字符设备连接到USB。 USB驱动程序与硬件接口通信以设置寄存器并传输数据。

在最高层次上,用户想要将文本输出到默认输出端口,这就是抽象。下面的层填充细节以完成工作。

耦合/依赖

两个或多个模块之间的依赖关系称为耦合。从紧密到松散有不同程度的耦合。当一个模块的内部更改需要对另一个模块进行更改时,两个模块被认为是紧密耦合的。当一个模块的内部更改不影响另一个模块时,两个模块被认为是松散耦合的。

松散耦合的目标是帮助减少整个系统中的变化传播。如果一个模块访问另一个模块的数据成员并且数据成员发生更改,则调用模块需要更改。如果调用模块使用接口,则提供程序可以更改其数据成员而不会影响调用模块。变化的传播已经停止。

总结

访问硬件不仅仅是编码。首先应考虑封装、变化传播、抽象和耦合原则。访问硬件的代码应遵循这些原则。一个好的过程是在编码之前考虑这些原则进行架构和设计。


谢谢您详细的回答。但是对于所问的问题来说,这不是有点太笼统了吗?;-) 不管怎样,还是非常感谢! - Michael
如果您喜欢这个答案或它对您有帮助,请点击勾选标记。 - Thomas Matthews

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接