C ++如何替换一个函数但仍然使用其中的原始函数?

时间:2010-08-16 15:53:55

标签: c++ opengl windows-xp function hook

我想修改glBindTexture()函数以跟踪先前绑定的纹理ID。目前我刚刚为它创建了新功能,但后来我意识到如果我使用其他使用glBindTexture的代码:那么我的整个系统可能会进入厕所。

那我该怎么做?

编辑:现在,当我想到它时,检查我是否应该绑定纹理是没用的,因为opengl可能已经这样做了。但我仍然需要跟踪以前使用的纹理。

6 个答案:

答案 0 :(得分:7)

正如安德烈亚斯在评论中所说,你应该检查一下是否有必要。但是,如果你想做这样的事情,并且你使用gnu链接器(你没有指定操作系统),你可以使用链接器选项:

--wrap glBindTexture

(如果直接给gcc你应该写):

-Wl,--wrap,glBindTexture

由于这是在链接器阶段完成的,您可以将新函数与已有的库一起使用(编辑:''库'我的意思是一些您可以重新编译但不想修改的现有代码)。

'替换'功能的代码如下所示:

void * __wrap_glBindTexture (GLenum target, GLuint texture) {
   printf ("glBindTexture wrapper\n");
   return __real_glBindTexture (target,texture);
}

答案 1 :(得分:3)

你实际上可以这样做。看看LD_PRELOAD。创建一个定义glBindTexture的共享库。要从包装器中调用原始实现,dlopen真正的OpenGL库,并使用dlsym从那里调用正确的函数。

现在让所有客户端代码LD_PRELOAD成为您的共享库,以便他们的OpenGL调用转到您的包装器。

这是拦截和修改对共享库的调用的最常用方法。

答案 2 :(得分:1)

您可以拦截并替换对glBindTexture的所有来电。要做到这一点,你需要创建自己的OpenGL DLL拦截所有OpenGL函数调用,进行所需的簿记,然后将函数调用转发到真正的OpenGL dll。这是很多的工作,所以在走这条路线之前我会三思而后行......

GLIntercept这样的程序就像这样工作。

答案 3 :(得分:0)

我从未使用过OpenGL,所以对这个功能一无所知,这是我最好的猜测。您可能希望将glBindTexture函数调用替换为代码中出现的新函数调用。如果你使用将在内部调用glBindTexture的库函数,那么你应该找到一种方法来反转glBindTexture的作用。然后,只要你调用绑定纹理的东西,就可以立即调用你的反转函数来撤消它的变化。

答案 4 :(得分:0)

一种可能性是使用宏来替换对glBindTexture的现有调用:

#define glBindTexture(target, texture) myGlBindTexture(target, texture)

然后在你想要确保不使用宏的代码中,用括号括起名字:

(glBindTexture)(someTarget, someTexture);

类似函数的宏仅在名称后面紧跟开括号的情况下替换,因此这会阻止宏扩展。

由于这是一个宏,它只会影响使用宏可见的源代码,而不是现有的DLL,静态库等。

答案 5 :(得分:0)

司机不会这样做,这是在规范中。你必须确保你没有绑定相同的纹理两次,所以这是一个好主意。

然而,分离问题甚至是一个更好的主意:让低级别的openGL处理​​其低级别的东西,而你的(瘦,厚,你想要的)抽象层可以处理更高级别的东西。

因此,创建一个执行if()的oglWrapper :: BindTexture函数,但是你不应该使用LD,即使这在技术上是可行的。

[编辑]事实上,它不在ogl规范中,但仍然存在。