当在同一文件中定义其调用函数时如何在 C 中模拟函数?
How to mock function in C when its caller function is defined in same file?
我正在尝试模拟 C 中的函数,当函数及其调用函数定义在不同的文件中时,模拟工作正常。但是当两个函数(函数本身和它的调用者)在同一个文件中定义时,模拟函数不会被调用。
案例 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");
}
案例二:
//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 中,模拟函数未被调用。我正在寻找一个可以模拟函数的解决方案,即使调用者和被调用函数在同一个文件中。
使用以两个下划线开头的函数名在 C 中是未定义的行为
(在你的情况下,我怀疑函数名称 __wrap_func
与 func
的 decorated 名称冲突,但这是推测性的并且完全依赖于编译器.)
您应该考虑使用 函数指针 的解决方案。
使用 --wrap=symbol
链接器选项将导致未定义的符号被解析为 __wrap_symbol
。
在您的第一种情况下, func
是未定义的符号,因此链接器将搜索 __wrap_func
并调用该函数。
在你的第二种情况下,链接器找到 myTest
因为它被声明为 extern
。
当 myTest
调用 func
时,它在同一个翻译单元中,因此不存在与 int func()
驻留在同一个文件中的 undefiend。所以原来的 func
是 calles 而不是 wrapped 版本。当调用者和被调用者位于同一文件以及不同文件中时,您的设计不适合使用模拟函数。
我建议您使用 MACRO
或 function pointer
技术,如 here.
所述
你不能。
--wrap symbol
Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to __wrap_symbol. Any undefined reference to
__real_symbol will be resolved to symbol. This can be used to provide a wrapper for a system function. The wrapper function should be called
__wrap_symbol. If it wishes to call the system function, it should call __real_symbol. Here is a trivial example:
void *
__wrap_malloc (int c)
{
printf ("malloc called with %ld\n", c);
return __real_malloc (c);
}
If you link other code with this file using --wrap malloc, then all calls to malloc will call the function __wrap_malloc instead. The
call to __real_malloc in __wrap_malloc will call the real malloc
function. You may wish to provide a __real_malloc function as well, so
that links without the --wrap option will succeed.
这是重要的部分...
If you do this, you
should not put the definition of __real_malloc in the same file as
__wrap_malloc; if you do, the assembler may resolve the call before the linker has a chance to wrap it to malloc.
我正在尝试模拟 C 中的函数,当函数及其调用函数定义在不同的文件中时,模拟工作正常。但是当两个函数(函数本身和它的调用者)在同一个文件中定义时,模拟函数不会被调用。
案例 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");
}
案例二:
//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 中,模拟函数未被调用。我正在寻找一个可以模拟函数的解决方案,即使调用者和被调用函数在同一个文件中。
使用以两个下划线开头的函数名在 C 中是未定义的行为
(在你的情况下,我怀疑函数名称 __wrap_func
与 func
的 decorated 名称冲突,但这是推测性的并且完全依赖于编译器.)
您应该考虑使用 函数指针 的解决方案。
使用 --wrap=symbol
链接器选项将导致未定义的符号被解析为 __wrap_symbol
。
在您的第一种情况下, func
是未定义的符号,因此链接器将搜索 __wrap_func
并调用该函数。
在你的第二种情况下,链接器找到 myTest
因为它被声明为 extern
。
当 myTest
调用 func
时,它在同一个翻译单元中,因此不存在与 int func()
驻留在同一个文件中的 undefiend。所以原来的 func
是 calles 而不是 wrapped 版本。当调用者和被调用者位于同一文件以及不同文件中时,您的设计不适合使用模拟函数。
我建议您使用 MACRO
或 function pointer
技术,如 here.
你不能。
--wrap symbol Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to __wrap_symbol. Any undefined reference to __real_symbol will be resolved to symbol. This can be used to provide a wrapper for a system function. The wrapper function should be called __wrap_symbol. If it wishes to call the system function, it should call __real_symbol. Here is a trivial example:
void * __wrap_malloc (int c) { printf ("malloc called with %ld\n", c); return __real_malloc (c); }
If you link other code with this file using --wrap malloc, then all calls to malloc will call the function __wrap_malloc instead. The call to __real_malloc in __wrap_malloc will call the real malloc function. You may wish to provide a __real_malloc function as well, so that links without the --wrap option will succeed.
这是重要的部分...
If you do this, you should not put the definition of __real_malloc in the same file as __wrap_malloc; if you do, the assembler may resolve the call before the linker has a chance to wrap it to malloc.