我正在尝试在C中模拟一个函数,当函数及其调用函数在不同的文件中定义时,mocking工作正常。但是当两个函数(函数本身及其调用者)在同一个文件中定义时,不会调用模拟函数。
案例1:
//test.c
#include <stdio.h>
/*mocked function*/
int __wrap_func() {
printf("Mock function !!!\n");
}
/*caller function*/
int myTest() {
return func();
}
int main() {
myTest();
return 0;
}
//file.c
#include<stdio.h>
/*function need to be mocked*/
int func() {
printf("Original function !!!\n");
}
案例2:
//test.c
#include <stdio.h>
extern int myTest();
/*mocked function*/
int __wrap_func() {
printf("Mock function !!!\n");
}
int main() {
myTest();
}
//file.c
#include<stdio.h>
/*function need to be mocked*/
int func() {
printf("Original function !!!\n");
}
/*caller function*/
int myTest() {
return func();
}
代码编译命令:gcc -Wl, - wrap = func test.c file.c
In Case 1 . Mock function !!!
In Case 2 . Original function !!!
在案例2中,未调用模拟函数。我正在寻找一个解决方案,我可以模拟函数,甚至调用者和被调用的函数都在同一个文件中。
答案 0 :(得分:3)
使用以两个下划线开头的函数名称是C中的未定义行为。
(在您的情况下,我怀疑函数名__wrap_func
与func
的修饰名称冲突,但这是推测性的,完全依赖于编译器。)
您应该考虑使用函数指针的解决方案。
答案 1 :(得分:1)
将导致使用--wrap=symbol
链接器选项,以便将未定义的符号解析为__wrap_symbol
。
在第一种情况下,func
是未定义的符号,因此链接器将搜索__wrap_func
并调用该函数。
在第二种情况下,链接器会找到myTest
,因为它被声明为extern
。
当myTest
调用func
时,它位于同一个翻译单元中,因此不会与作为int func()
的文件驻留在同一文件中。所以原来的func
是calles而不是包装版本。当调用者和被调用者在同一文件中以及在不同文件中时,您的设计不适合使用模拟函数。
我建议您使用MACRO
或function pointer
技术解释here。
答案 2 :(得分:1)
你不能。
- 换行符号 使用符号包装函数。任何未定义的符号引用都将解析为__wrap_symbol。任何未定义的引用 __real_symbol将被解析为符号。这可用于为系统功能提供包装器。应该调用包装函数 __wrap_symbol。如果它想调用系统函数,它应该调用__real_symbol。这是一个简单的例子:
void * __wrap_malloc (int c) { printf ("malloc called with %ld\n", c); return __real_malloc (c); }
如果使用--wrap malloc将其他代码与此文件链接,则对malloc的所有调用都将调用函数__wrap_malloc。该 在__wrap_malloc中调用__real_malloc将调用真正的malloc 功能。您可能也希望提供__real_malloc函数,所以 没有--wrap选项的链接会成功。
这是重要的一部分......
如果你这样做,你 不应该将__real_malloc的定义放在同一个文件中 --wrap malloc中调用;如果这样做,汇编器可以在链接器有机会将其包装到malloc之前解析调用。