GNU 链接器有一个--wrap <symbol>
允许您执行此类操作的选项。
如果您链接到--wrap write
, 参考文献write
将重定向到__wrap_write
(您实现的),以及对的引用__real_write
将重定向到原来的write
(因此您可以从包装器实现中调用它)。
这是一个复杂的测试应用程序,使用write()
- 我分别执行编译和链接步骤,因为我想使用hello.o
一分钟后再次:
$ cat hello.c
#include <unistd.h>
int main(void)
{
write(0, "Hello, world!\n", 14);
return 0;
}
$ gcc -Wall -c hello.c
$ gcc -o test1 hello.o
$ ./test1
Hello, world!
$
这是一个实现__wrap_write()
,这称为__real_write()
。 (请注意,我们想要一个原型__real_write
以匹配原来的。我已经明确添加了一个匹配的原型,但另一个可能的选择是#define write __real_write
before #include <unistd.h>
.)
$ cat wrapper.c
#include <unistd.h>
extern ssize_t __real_write(int fd, const void *buf, size_t n);
ssize_t __wrap_write(int fd, const void *buf, size_t n)
{
__real_write(fd, "[wrapped] ", 10);
return __real_write(fd, buf, n);
}
$ gcc -Wall -c wrapper.c
$
现在,链接hello.o
我们之前做的wrapper.o
,将适当的标志传递给链接器。 (我们可以通过任意选项gcc
使用稍微奇怪的链接器-Wl,option
句法。)
$ gcc -o test2 -Wl,--wrap -Wl,write hello.o wrapper.o
$ ./test2
[wrapped] Hello, world!
$