【发布时间】:2013-03-11 08:44:46
【问题描述】:
我创建了一个看起来像数组的类,但不是在程序本身中保存数据,而是从文件中流式传输字节(以减少对 RAM 的影响)。现在我已经完成了所有这些工作,但程序员必须使用以下内容定义类:
#define CreateReadOnlyBlock(name, location, size, ...) \
template<> \
const unsigned int ReadOnlyBlock<location, size>::Data[] \
__asm__( ".readonly__" #location "__" #name) \
= { __VA_ARGS__ }; \
ReadOnlyBlock<location, size> name;
例子:
//A read only array of {0, 1, 2, 3}
CreateReadOnlyBlock(readOnlyArray, 0, 4, 0, 1, 2, 3);
请注意,这是针对嵌入式处理器的,asm 指令通过汇编器中的工具来创建只读文件。
所以这是我的问题:如何消除“位置”和“大小”变量?我讨厌程序员必须手动输入它们,并且更喜欢在编译时生成它们的某种方式。所以程序员不需要输入:
//A read only array at location 0 of {0, 1, 2, 3}
CreateReadOnlyBlock(readOnlyArray1, 0, 4, 0, 1, 2, 3);
//A read only array at location 4 of {4, 5, 6, 7}
CreateReadOnlyBlock(readOnlyArray2, 4, 4, 4, 5, 6, 7);
他们可以输入:
CreateReadOnlyBlock(readOnlyArray1, 0, 1, 2, 3);
CreateReadOnlyBlock(readOnlyArray2, 4, 5, 6, 7);
并且会生成适当的常量。基本上,我正在寻找某种方法来在编译时根据先前的定义生成和放置这些常量。 C ++ 11 是公平的游戏,我只是不太熟悉它(带有 constexpr 的东西似乎是合理的?)。此外,如果 C-Preprocessor 不会使它变得比现在更丑,它也可以。这可能吗?
为清楚起见进行编辑:
ReadOnlyBlock 类中有这个方法:
template<const int _location, const int _size> class ReadOnlyBlock
{
...
unsigned int operator[] (size_t index)
{
return LoadFromROM(index + _location);
}
}
位置变量和 ROM 文件之间存在内在的相互依赖关系,我想不出如何破解。但是,我确实也可以完全控制工具链,但我需要一种方法来传递汇编器工具如何构造文件以及向 C++ 代码指示块所在的位置文件。
另一个编辑:
文件及其块可能相当很大,多达 1k 个字,因此很多预处理器的魔法可能会因此崩溃。另外,感谢大家迄今为止的帮助!
【问题讨论】:
-
#location中的__asm__部分真的很糟糕。您真的需要这个,还是只对其余的解决方案感到满意? -
大小很容易,但位置需要上下文。模板实例化是一种函数式语言,实例化的结果只能根据您传入的内容而有所不同。如果您将这些块链接起来,或者在一个大模板中创建内存,则可以完成。即,创建一个
tuple的只读数组,每个数组都有一个位置和大小,从某个位置开始并打包。 -
所以也许我应该包括原因。 ReadOnlyBlock 类中重载的 [] 运算符调用 LoadFromROM(index + location);该工具创建一个只读文件,该文件在每个指定位置具有每个块,并且该类知道从该位置加载。我想不出一种方法来消除这种相互依赖,但我确实可以完全控制该工具以及访问代码,因此更改它并不是不可能的。
-
哦,我刚刚注意到您在编译时使用了
location的字符串值,将包含它的字符串文字连接起来,然后将结果传递给__asm__。您的__asm__是否支持constexpr字符串? :) -
我真的不确定。我正在使用带有自定义 LLVM 后端的 Clang 3.0。
标签: c++ c++11 embedded c-preprocessor