我想在运行时知道C函数的长度(由我编写)。任何获得它的方法?似乎sizeof在这里不起作用。
答案 0 :(得分:17)
有一种方法可以确定函数的大小。命令是:
nm -S <object_file_name>
这将返回目标文件中每个函数的大小。使用'man nm'查阅GNU中的手册页以收集更多相关信息。
答案 1 :(得分:14)
标准C中无法获取函数占用的内存量。
答案 2 :(得分:13)
如果使用自定义链接描述文件,则可以从链接器获取此信息。仅为给定函数添加链接器部分,并在任一侧添加链接器符号:
mysec_start = .;
*(.mysection)
mysec_end = .;
然后您可以专门将该功能分配给该部分。符号之间的差异是函数的长度:
#include <stdio.h>
int i;
__attribute__((noinline, section(".mysection"))) void test_func (void)
{
i++;
}
int main (void)
{
extern unsigned char mysec_start[];
extern unsigned char mysec_end[];
printf ("Func len: %lu\n", mysec_end - mysec_start);
test_func ();
return 0;
}
此示例适用于GCC,但任何C工具链都应该有一种方法来指定要为其分配函数的部分。我会根据汇编列表检查结果,以验证它是否按照您希望的方式工作。
答案 3 :(得分:4)
可执行文件(至少已剥离调试信息的文件)不以任何方式存储函数长度。因此,不可能在运行时通过self解析此信息。如果必须使用函数进行操作,则应在链接阶段对象或从可执行文件中将文件作为文件访问。例如,您可以告诉链接器将符号表作为普通数据部分链接到可执行文件中,为它们分配一些名称,并在程序运行时进行解析。但请记住,这将特定于您的链接器和对象格式。
另请注意,功能布局也是特定于平台的,并且有些事情使“功能长度”一词不明确:
他们都可以计算或不计算函数长度。
此外,函数可能会被编译器完全内联,因此它会松散它的主体。
答案 4 :(得分:3)
例如Codewarrior,您可以在函数周围放置标签,例如
label1:
void someFunc()
{
/* code goes here. */
}
label2:
然后像(int)(label2-label1)
那样计算大小,但这显然与编译器有关。根据您的系统和编译器,您可能必须破解链接器脚本等。
答案 5 :(得分:3)
函数的开头是函数指针,你已经知道了。
问题是找到结束,但可以这样做:
#include <time.h>
int foo(void)
{
int i = 0;
++i + time(0); // time(0) is to prevent optimizer from just doing: return 1;
return i;
}
int main(int argc, char *argv[])
{
return (int)((long)main - (long)foo);
}
它在这里工作,因为程序只有两个函数,所以如果代码重新排序(主要在foo之前实现)那么你将得到一个无关的(负面)计算,让你知道它不是这样工作但是那个如果你将foo()代码移动到main()中它会工作 - 只需减去初始否定回复所带来的main()大小。
如果结果是肯定的,那么它将是正确的 - 如果没有填充(是的,一些编译器愉快地膨胀代码,无论是为了对齐还是为了其他不太明显的原因)。
结束(int)(long)强制转换是为了在32位和64位代码之间实现可移植性(64位平台上的函数指针会更长)。
这是便携式的,应该可以很好地工作。
答案 6 :(得分:1)
在C语言本身中没有定义任何工具来返回函数的长度;涉及的变量太多(编译器,目标指令集,目标文件/可执行文件格式,优化设置,调试设置等)。完全相同的源代码可能导致不同系统的不同大小的功能。
C根本不提供任何类型的反射功能来支持这种信息(尽管个别编译器可能提供扩展,例如sskuce引用的Codewarrior示例)。如果您需要知道函数占用内存的字节数,那么您必须直接检查生成的对象或可执行文件。
sizeof func
将无效,因为表达式func
被视为指向函数的指针,因此您获得指针值的大小,而不是函数本身。
答案 7 :(得分:1)
我刚刚针对完全相同的问题提出了解决方案,但我编写的代码取决于平台。
背后的想法是,将已知操作码放在函数的末尾,并在计算我们已跳过的字节的同时从头开始搜索它们。 这是我用一些代码解释的媒体链接 https://medium.com/@gurhanpolat/calculate-c-function-size-x64-x86-c1f49921aa1a
答案 8 :(得分:0)
在C或C ++中没有标准的方法。可能自然存在实现/平台特定的doiung方式,但我不知道任何
答案 9 :(得分:0)
如果你是为 x86 编译,你可以试试这个
int GetFuncSizeX86(unsigned char* Func)
{
if (!Func)
return 0;
// printf("Getting the Function Size on ===> %08X\n", Func);
int count = 0;
KeepCount:
while (*Func != 0xC3)
{
//printf("Current Opcode ==> %01X\n", *Func);
Func++;
count++;
}
//printf("C3 Opcode Found\n");
//printf("Back Opcode ==> %01X\n", *(Func - 1));
//printf("Next Opcode ==> %01X\n", *(Func + 1));
if (*(Func + 1) == 0xCC
|| *(Func - 1) == 0x5D
|| *(Func - 1) == 0x5B
|| *(Func - 1) == 0x5E
|| *(Func - 1) == 0x5F
|| *(Func - 1) == 0xCC
|| *(Func - 1) == 0xC9)
{
count++;
return count;
}
else
{
Func++;
count++;
goto KeepCount;
}
}
只需将函数强制转换为 char*
答案 10 :(得分:-3)
您可以通过减去函数的地址来找到C函数的长度。 让我举个例子
int function1()
{
}
int function2()
{
int a,b; //just defining some variable for increasing the memory size
printf("This function would take more memory than earlier function i.e function01 ");
}
int main()
{
printf("Printing the address of function01 %p\n",function01);
printf("Printing the address of function02 %p\n",function02);
printf("Printing the address of main %p\n",main);
return 0;
}
希望你在编译之后得到你的答案。编译后你就能看到了 function01和function2的大小差异。
注意:通常一个函数与另一个函数之间存在16字节差异。