使用某些编译器,您可以通过计算函数地址与紧随第一个函数的另一个函数的地址之间的差异来获得函数大小。
但这真的取决于编译器。以 Visual C++ 为例,这两个函数都必须是 static 函数。使用 GCC,如果优化 O2 或更高版本被激活,它将不再起作用。
即使您设法将您的函数复制到内存中的其他位置,您也可能无法使用它,特别是如果它引用其他函数,或者如果它引用全局/静态变量,或者如果代码不是位置独立的,等等
所以这是一个简单的解决方案,它可能适用于您的情况,但不能被视为通用解决方案。
下面是一个使用 gcc 和 Visual C++ 的示例,在 Windows 10 和 WSL 上进行了测试(不要使用 gcc 激活优化)。
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#endif
#ifdef __linux
#include <sys/mman.h>
#endif
// The function to copy
static int fib(int m)
{
int v1 = 0, v2 = 1, n;
if (m == 0) return 0;
for (n = 1; n < m; n++)
{
int v = v1 + v2;
v1 = v2;
v2 = v;
}
return v2;
}
static void endFib(void)
{
// This function follow immediatly the fib function
// and it exists only to get its address and compute the size of fib function
}
int main(int argc, char *argv)
{
long sizeFib;
int (*copyFib)(int);
printf("&fib=%p\n", (char *)fib);
sizeFib = (char *)endFib - (char *)fib;
printf("size of fib : %ld\n", sizeFib);
printf("fib(8) : %d\n", fib(8));
// For the example the allocated copy must be in an executable part of the memory.
#ifdef _WIN32
copyFib = VirtualAlloc(NULL, sizeFib, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#endif
#ifdef __linux
copyFib = mmap(NULL, sizeFib, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
#endif
memcpy(copyFib, fib, sizeFib);
printf("©Fib=%p\n", copyFib);
printf("copyFib(8) : %d\n", copyFib(8));
return 0;
}