我尝试实现基于地址(值)的数据访问。我的地址范围是0x0000-0xFFFF,并且根据地址不同,数据访问的功能也不同。
直到现在,我使用了一个开关盒实现,它确实根据给定的地址选择了正确的功能。 现在,我正在通过使用地图寻找新的解决方案。这个想法是,键是一个包含开始值和结束值(在地址范围内)的对象。映射条目是一个函数指针,当地址在范围内时应调用该指针。
要找到正确的函数指针,我将使用具有单个值(地址)的find方法。为此,我还实现了operator <。
不幸的是,find函数在Map中找不到任何条目。有没有人看到可能的问题?还是有更好的主意来解决我的问题?
struct RegAdr {
uint32_t start;
uint32_t end;
RegAdr() = delete;
RegAdr(uint32_t value);
RegAdr(uint32_t start, uint32_t end);
bool operator<(const RegAdr& rhs) const {
return this->end < rhs.end;
}
bool operator>(const RegAdr& rhs) const {
return rhs < *this;
}
bool operator<=(const RegAdr& rhs) const {
return !(*this > rhs);
}
bool operator>=(const RegAdr& rhs) const {
return !(*this < rhs);
}
bool operator==(const RegAdr& rhs) const {
return (this->start <= rhs.start && this->end >= rhs.start);
}
bool operator!=(const RegAdr& rhs) const {
return !(*this == rhs);
}
bool operator()(const RegAdr& rhs) const {
return !((this->end < rhs.start) || (rhs.end < this->start));
}
};
答案 0 :(得分:1)
首先,您需要注意重叠范围。我想你已经做到了。
由于允许值的范围是固定的(并且不是那么大),所以解决方案可能非常简单。
您的选择:
使用0x10000元素的固定数组作为查找表。添加新范围后,将所有相应条目设置为给定的函数指针。您可以获得恒定的时间查找,但要花费额外的内存,插入时间与范围大小成正比。
如上所述,但是使用哈希表(std::unordered_map
)。
使用一对RegAdr
和函数指针组成的容器,例如std::vector<std::pair<RegAdr, func_ptr>>
。插入很简单。在寻址时,请遍历容器并检查给定的地址是否在范围内。您可以获得(摊销的)固定时间插入,并且以与范围数成正比的查找时间为代价,将内存使用降至最低。
答案 1 :(得分:0)
基于@Krzysiek Karbowiak给出的选项,我实现了基于矢量的解决方案。对于对该解决方案感兴趣的任何人,我都会添加一些代码片段:
向量定义和初始化:
typedef int (DataRead::*readPtr)(const uint32_t address, void* buffer, uint32_t* bufSize);
std::map<RegAdr, readPtr> readMap;
std::vector<std::pair<RegAdr, readPtr>> readVector;
RegAdr localMemory(0x0000,0x0255);
readVector.push_back(std::make_pair(localMemory, &DataRead::readLocalMemory));
RegAdr libraryMemory(0x1000,0x1255);
readVector.push_back(std::make_pair(libraryMemory, &DataRead::readLibraryMemory));
用于基于地址的数据访问的功能:
int DataRead::readMemory(const uint32_t address, void* buffer, uint32_t* bufSize) {
int ret = -42;
for (auto element : readVector) {
uint32_t elementStart = element.first.start;
uint32_t elementEnd = element.first.end;
if (elementStart <= address && address <= elementEnd) {
// address in range
auto rfp = element.second;
ret = (this->*rfp)(address, buffer, bufSize);
break;
}
}
if (ret == -42) {
char cMsg[] = "Mover Thread read failed! Address not found!";
std::vector<uint8_t> vMsg(cMsg, cMsg + sizeof(cMsg));
sharedData->threadData->setStream(Addr::MOVER_LAST_ERROR, vMsg);
}
if (ret < 0) {
// error message should be written in function call...
bufSize = 0;
return -1;
}
return 0;
}
感谢所有人,尤其是Krzysiek Karbowiak的提示!