我需要在运行时确定c函数的字节大小。我正在使用MSVC,我可以使用此编译器提供的任何技术。
我知道这个问题已被问过很多,但我只能找到人们说“不,不可能”。不过,也许我已经监督了一个解决方案。如果是这种情况,请指出我。
答案 0 :(得分:5)
通常,它按照函数在源代码中出现的顺序以合理的方式生成代码。所以大小是下一个函数的地址减去函数的地址。
然而,有几种方法不能很好地解决问题。首先是增量链接选项,您将获得值5.这是跳转到实际函数的jmp指令的大小。这些跳转允许链接器替换代码而不完全重新链接图像,它只是附加代码并修补跳转地址。
当然还有优化器。当内联时,你不能再有意义地谈论函数大小。你需要__declspec(noinline)。
可以做,测试它并彻底评论代码,这样有一天没有人会插入一个函数。如果你这样做是为了移动代码,请务必记住编译器不会生成与位置无关的代码,也无法修补该代码的重定位。
答案 1 :(得分:1)
如果你真的感兴趣,可以从MSVC编译成.asm,然后计算出函数开始标签和自定义标签之间的字节差异,计算它们之间的差异。 :)通常,编译器不会生成函数结束标签......只是开头。
除非函数需要在内存中重新定位并调用!
,否则通常不会使用它答案 2 :(得分:1)
我认为这应该是可能的。您的一些进展取决于您需要的结果的准确程度。如果可以接受一些可能的不准确,我的第一选择是SymEnumSymbols
。您提供了一个回调函数,可以调用适合您指定的过滤器的每个符号。您的回调函数将被赋予每个符号的名称和计算(猜测)大小。当你得到正确的符号时,你已经得到了它为你的函数猜测/计算的大小(虽然要注意:它也可以说大小为0,所以你可能需要做一些测试来获得一个好主意它可能对你想要的东西有效。
一点测试表明,在函数的情况下,这个似乎是相当准确的(我有点担心这可能是它会返回0的情况)。请注意,您通常希望使用调试信息进行构建以使用它(导出您关心的函数可能就足够了)。
另一种可能性(虽然可能更复杂)是使用#pragma code_seg
将您关心的函数单独放在一个部分中,并使用唯一的部分名称,然后遍历PE文件以查找该部分的大小