覆盖C中的函数调用

覆盖C中的函数调用

我想为了记录调用而覆盖对各种API的某些函数调用,但我也可能希望在将数据发送到实际函数之前对其进行操作。

例如,假设我getObjectName在源代码中使用了一个名为数千次的函数。我想暂时覆盖此函数,因为我想更改此函数的行为以查看不同的结果。

我创建了一个像这样的新源文件:

#include <apiheader.h>    const char *getObjectName (object *anObject){
    if (anObject == NULL)
        return "(null)";
    else
        return "name should be here";}

我像往常一样编译所有其他源代码,但是在链接API的库之前我首先将它链接到此函数。这工作正常,但我显然不能在我的重写函数中调用真正的函数。

是否有一种更简单的方法来“覆盖”一个函数而不会链接/编译错误/警告?理想情况下,我希望能够通过编译和链接一个或多个额外的文件来覆盖该函数,而不是通过链接选项或改变我的程序的实际源代码。


qq_遁去的一_1
浏览 572回答 3
3回答

潇湘沐

如果您只想为您的源捕获/修改调用,最简单的解决方案是将头文件(intercept.h)放在一起:#ifdef&nbsp;INTERCEPT&nbsp;&nbsp;&nbsp;&nbsp;#define&nbsp;getObjectName(x)&nbsp;myGetObectName(x)#endif并实现如下功能(intercept.c其中不包括intercept.h):const&nbsp;char&nbsp;*myGetObjectName&nbsp;(object&nbsp;*anObject)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(anObject&nbsp;==&nbsp;NULL) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"(null)"; &nbsp;&nbsp;&nbsp;&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;getObjectName(anObject);}然后确保要拦截呼叫的每个源文件具有:#include&nbsp;"intercept.h"在顶部。然后,当你用“&nbsp;-DINTERCEPT”&nbsp;编译时,所有文件都会调用你的函数而不是真正的函数,你的函数仍然可以调用真函数。没有“&nbsp;-DINTERCEPT”的编译将防止发生拦截。如果你想拦截所有的电话(不仅仅是来自你的电话),这有点棘手 - 这通常可以通过动态加载和解析真实函数(带dlload-和dlsym-类型调用)来完成,但我不认为这是你的必要案件。

犯罪嫌疑人X

使用gcc,在Linux下你可以--wrap像这样使用链接器标志:gcc&nbsp;program.c&nbsp;-Wl,-wrap,getObjectName&nbsp;-o&nbsp;program并将您的功能定义为:const&nbsp;char&nbsp;*__wrap_getObjectName&nbsp;(object&nbsp;*anObject){ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(anObject&nbsp;==&nbsp;NULL) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"(null)"; &nbsp;&nbsp;&nbsp;&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;__real_getObjectName(&nbsp;anObject&nbsp;);&nbsp;//&nbsp;call&nbsp;the&nbsp;real&nbsp;function}这将确保将所有调用getObjectName()重新路由到您的包装函数(在链接时)。然而,在Mac OS X下的gcc中没有这个非常有用的标志。extern "C"如果您正在使用g ++编译,请记住声明包装函数。
打开App,查看更多内容
随时随地看视频慕课网APP