我正在为微 Controller 编写一些代码,我需要根据函数指针查找数据(这些数据和函数将在 ROM 中)。
我希望能够相对快速地执行此操作,并且无需将 RAM 用于查找表。我能想到的最简单的方法是进行二进制搜索。
我只是把它作为一个例子,所以它可能会被破坏,但希望你能理解:
void myFunction1() {}
void myFunction2() {}
void myFunction3() {}
void myFunction4() {}
// ...
typedef struct {
void *functionPtr;
int myData[10];
} SearchData;
const SearchData mySearchData[] = {
{ &myFunction1, ... },
{ &myFunction2, ... },
{ &myFunction3, ... },
{ &myFunction4, ... },
// ...
};
void doBinarySearch(void *func, int min, int max) {
if (max<min) return;
int mid = (min+max)/2;
if (func < mySearchData[mid].functionPtr)
doBinarySearch(func, min, mid-1);
else if (func > mySearchData[mid].functionPtr)
doBinarySearch(func, mid+1, max);
else {
// we found it!
}
}
void realBinarySearch(void *func) {
doBinarySearch(func, 0, (sizeof(mySearchData)/sizeof(SearchData))-1);
}
然而,要使其工作,myFunction1
、myFunction2
等需要在内存中一个接一个地布置(尽管不一定彼此相邻)。我需要使用 -Os
编译所有内容以适应可用的 ROM,那么我如何确保函数实际上保持正确的顺序?
...或者失败了,我如何重新排序 mySearchData
使其与函数的顺序相匹配?
我现在唯一能想到的是:
- 构建整个东西,然后进行后处理步骤,在二进制文件中对数组进行排序 - 虽然非常不便携。
- 构建一次,查看列表文件找出函数的真实顺序,重写
mySearchData
并再次编译 - 但不能保证编译器是确定性的
虽然这些听起来都不太好。
最佳答案
好的,。我真的不明白为什么你需要一个指向 SEARCH 的函数指针......将数据放入函数要简单得多,在这种情况下也会重新排序。但你要求的是那个。
OK,给出C代码中的gcc:
您可以通过添加以下内容将每个函数放在其自己的部分中:
void f1() __attribute__((section(".text.1")));
void f1()
{
}
void f2() __attribute__((section(".text.2")));
void f2()
{
}
void f3() __attribute__((section(".text.3")));
void f3()
{
}
然后您使用修改后的链接描述文件,如下所示:
.text :
{
....
*(.text.1)
*(.text.2)
*(.text.3)
... continues here ...
在链接器脚本中还有更多的可能性来对输入节进行排序。查看 SORT 的 ld 描述!
摘自ld手册:
通常,链接器会按照在链接过程中看到的顺序放置通配符匹配的文件和节。您可以使用 SORT 关键字更改此设置,该关键字出现在括号中的通配符模式之前(例如,SORT(.text*))。当使用 SORT 关键字时,链接器将在将文件或节放入输出文件之前按名称升序排序。
但作为评论,我相信你有一个 XY 问题。我想你会做一些事情,排序功能和处理二进制搜索是你的解决方案。我相信没有这些 hack 也可以解决 origin 问题!
如果能得到你原来的问题就好了!
关于c - 海湾合作委员会 + C : Keeping Functions in order in the binary file,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32013677/