我想修改glBindTexture()函数来跟踪以前绑定的纹理ID。目前我刚刚为它创建了新函数,但后来我意识到,如果我使用其他使用glBindTexture的代码:那我整个系统都要完蛋了那我该怎么做?
**编辑:**现在当我想到它的时候,检查是否应该绑定纹理是非常无用的,因为opengl可能已经这样做了。但是我仍然需要跟踪以前使用的纹理。
r6hnlfcb1#
正如Andreas在评论中所说的,你应该检查这是必要的。不过,如果你想做这样的事情,并且你使用了gnu链接器(你没有指定操作系统),你可以使用链接器选项:
--wrap glBindTexture
(if直接交给gcc,您应该写):
-Wl,--wrap,glBindTexture
由于这是在链接器阶段完成的,因此您可以将新函数与现有库一起使用(编辑:“库”是指一些可以重新编译但不想修改的现有代码)。“replacement”函数的代码如下所示:
void * __wrap_glBindTexture (GLenum target, GLuint texture) { printf ("glBindTexture wrapper\n"); return __real_glBindTexture (target,texture); }
rsaldnfx2#
你实际上 * 可以 * 做到这一点。看看LD_PRELOAD。创建一个定义glBindTexture的共享库。要从 Package 器中调用原始实现,dlopen是真实的的OpenGL库,并使用dlsym从那里调用正确的函数。现在,让所有客户端代码LD_PRELOAD您的共享库,以便它们的OpenGL调用转到您的 Package 器。这是截取和修改对共享库的调用的最常用方法。
glBindTexture
dlopen
dlsym
h22fl7wq3#
您可以拦截和替换所有对glBindTexture的调用。要做到这一点,您需要创建自己的OpenGL dll,它拦截所有OpenGL函数调用,做您想要的簿记,然后将函数调用转发到真实的的OpenGL dll。这是一个 * 大量 * 的工作,所以我肯定会三思而后行...像GLIntercept这样的程序是这样工作的。
xwbd5t1u4#
一种可能性是使用宏替换对glBindTexture的现有调用:
#define glBindTexture(target, texture) myGlBindTexture(target, texture)
然后,在您的程式码中,如果您要确保不使用宏,请将名称括在括号中:
(glBindTexture)(someTarget, someTexture);
类似函数的宏只会在名称后面紧跟左括号的地方被取代,因此这会防止宏展开。由于这是一个宏,因此它只会影响使用可见宏编译的源代码,而不会影响现有的DLL、静态库等。
bnl4lu3b5#
我从来没有使用过OpenGL,所以对这个函数一无所知,这是我最好的猜测。你可能想用你的新函数在代码中的任何地方调用来替换glBindTexture函数调用。如果你使用的库函数会在内部调用glBindTexture,那么你可能应该找到一种方法来逆转glBindTexture所做的事情。然后,每当你调用绑定纹理的东西时,您可以立即调用撤消函数来撤消其更改。
6uxekuva6#
驱动程序不会这样做,这是在规格。你必须确保你不绑定相同的纹理两次,所以这是一个好主意。但是,将这些问题分开更好:让低级别的openGL处理它的低级别内容,而您的(瘦、厚,根据您的需要)抽象层处理高级别的内容。因此,创建一个oglWrapper::BindTexture函数来执行if(),但不应使用LD,即使这在技术上是可能的。事实上,这并不是在ogl规范中,但仍然是。
mbyulnm07#
一般来说,这些方法被归类在“接缝”的标题下,正如M. Feather在2004年出版的《有效地使用遗留代码》一书中所普及的那样。这本书的重点是在一个整体应用程序中找到接缝,以隔离它的各个部分,并将它们置于自动测试之下。羽毛的接缝可以在以下地方找到
__attribute__ ((ifunc
#define
-Wl,--wrap,func_xyz
dlsym(RTLD_NEXT, ...)
来源:
7条答案
按热度按时间r6hnlfcb1#
正如Andreas在评论中所说的,你应该检查这是必要的。不过,如果你想做这样的事情,并且你使用了gnu链接器(你没有指定操作系统),你可以使用链接器选项:
(if直接交给gcc,您应该写):
由于这是在链接器阶段完成的,因此您可以将新函数与现有库一起使用(编辑:“库”是指一些可以重新编译但不想修改的现有代码)。
“replacement”函数的代码如下所示:
rsaldnfx2#
你实际上 * 可以 * 做到这一点。看看LD_PRELOAD。创建一个定义
glBindTexture
的共享库。要从 Package 器中调用原始实现,dlopen
是真实的的OpenGL库,并使用dlsym
从那里调用正确的函数。现在,让所有客户端代码LD_PRELOAD您的共享库,以便它们的OpenGL调用转到您的 Package 器。
这是截取和修改对共享库的调用的最常用方法。
h22fl7wq3#
您可以拦截和替换所有对
glBindTexture
的调用。要做到这一点,您需要创建自己的OpenGL dll,它拦截所有OpenGL函数调用,做您想要的簿记,然后将函数调用转发到真实的的OpenGL dll。这是一个 * 大量 * 的工作,所以我肯定会三思而后行...像GLIntercept这样的程序是这样工作的。
xwbd5t1u4#
一种可能性是使用宏替换对glBindTexture的现有调用:
然后,在您的程式码中,如果您要确保不使用宏,请将名称括在括号中:
类似函数的宏只会在名称后面紧跟左括号的地方被取代,因此这会防止宏展开。
由于这是一个宏,因此它只会影响使用可见宏编译的源代码,而不会影响现有的DLL、静态库等。
bnl4lu3b5#
我从来没有使用过OpenGL,所以对这个函数一无所知,这是我最好的猜测。你可能想用你的新函数在代码中的任何地方调用来替换glBindTexture函数调用。如果你使用的库函数会在内部调用glBindTexture,那么你可能应该找到一种方法来逆转glBindTexture所做的事情。然后,每当你调用绑定纹理的东西时,您可以立即调用撤消函数来撤消其更改。
6uxekuva6#
驱动程序不会这样做,这是在规格。你必须确保你不绑定相同的纹理两次,所以这是一个好主意。
但是,将这些问题分开更好:让低级别的openGL处理它的低级别内容,而您的(瘦、厚,根据您的需要)抽象层处理高级别的内容。
因此,创建一个oglWrapper::BindTexture函数来执行if(),但不应使用LD,即使这在技术上是可能的。
事实上,这并不是在ogl规范中,但仍然是。
mbyulnm07#
一般来说,这些方法被归类在“接缝”的标题下,正如M. Feather在2004年出版的《有效地使用遗留代码》一书中所普及的那样。这本书的重点是在一个整体应用程序中找到接缝,以隔离它的各个部分,并将它们置于自动测试之下。
羽毛的接缝可以在以下地方找到
__attribute__ ((ifunc
,https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html#define
使用的内容-Wl,--wrap,func_xyz
dlsym(RTLD_NEXT, ...)
进行委托来源: