opengl C++如何替换一个函数,但仍然使用原来的函数?

bogh5gae  于 2022-11-23  发布在  其他
关注(0)|答案(7)|浏览(118)

我想修改glBindTexture()函数来跟踪以前绑定的纹理ID。目前我刚刚为它创建了新函数,但后来我意识到,如果我使用其他使用glBindTexture的代码:那我整个系统都要完蛋了
那我该怎么做?

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

r6hnlfcb

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);
}
rsaldnfx

rsaldnfx2#

你实际上 * 可以 * 做到这一点。看看LD_PRELOAD。创建一个定义glBindTexture的共享库。要从 Package 器中调用原始实现,dlopen是真实的的OpenGL库,并使用dlsym从那里调用正确的函数。
现在,让所有客户端代码LD_PRELOAD您的共享库,以便它们的OpenGL调用转到您的 Package 器。
这是截取和修改对共享库的调用的最常用方法。

h22fl7wq

h22fl7wq3#

您可以拦截和替换所有对glBindTexture的调用。要做到这一点,您需要创建自己的OpenGL dll,它拦截所有OpenGL函数调用,做您想要的簿记,然后将函数调用转发到真实的的OpenGL dll。这是一个 * 大量 * 的工作,所以我肯定会三思而后行...
GLIntercept这样的程序是这样工作的。

xwbd5t1u

xwbd5t1u4#

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

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

然后,在您的程式码中,如果您要确保不使用宏,请将名称括在括号中:

(glBindTexture)(someTarget, someTexture);

类似函数的宏只会在名称后面紧跟左括号的地方被取代,因此这会防止宏展开。
由于这是一个宏,因此它只会影响使用可见宏编译的源代码,而不会影响现有的DLL、静态库等。

bnl4lu3b

bnl4lu3b5#

我从来没有使用过OpenGL,所以对这个函数一无所知,这是我最好的猜测。你可能想用你的新函数在代码中的任何地方调用来替换glBindTexture函数调用。如果你使用的库函数会在内部调用glBindTexture,那么你可能应该找到一种方法来逆转glBindTexture所做的事情。然后,每当你调用绑定纹理的东西时,您可以立即调用撤消函数来撤消其更改。

6uxekuva

6uxekuva6#

驱动程序不会这样做,这是在规格。你必须确保你不绑定相同的纹理两次,所以这是一个好主意。
但是,将这些问题分开更好:让低级别的openGL处理它的低级别内容,而您的(瘦、厚,根据您的需要)抽象层处理高级别的内容。
因此,创建一个oglWrapper::BindTexture函数来执行if(),但不应使用LD,即使这在技术上是可能的。
事实上,这并不是在ogl规范中,但仍然是。

mbyulnm0

mbyulnm07#

一般来说,这些方法被归类在“接缝”的标题下,正如M. Feather在2004年出版的《有效地使用遗留代码》一书中所普及的那样。这本书的重点是在一个整体应用程序中找到接缝,以隔离它的各个部分,并将它们置于自动测试之下。
羽毛的接缝可以在以下地方找到

  • 编译程序
  • GCC中的__attribute__ ((ifunchttps://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html
  • 预处理器
  • 更改#define使用的内容
  • 连接器
  • -Wl,--wrap,func_xyz
  • 链接顺序,使用找到第一个符号,程序可以使用dlsym(RTLD_NEXT, ...)进行委托
  • 二进制格式有一个过程链接表,当程序运行时,它可以由程序本身修改
  • 在Java中,JVM中可以实现很多功能,例如参见Mockito
  • 语言特征
  • 函数指针,这实际上可以做到,以便在调用点不增加语法开销!
  • 对象继承:继承、覆写、呼叫super()

来源:

相关问题