使用javassist编辑本机方法类?

Fel*_*lix 5 java javassist

使用Javassist,有没有办法将代码注入本机方法?在这种情况下,我试图让我的游戏中的OpenGL调用在调用时打印出他们的名字和值,但是当我假设添加了openGL DLL代码时,我的所有尝试都会遇到错误.

该方法看起来像:

public static native void glEnable(int paramInt);
Run Code Online (Sandbox Code Playgroud)

由于这些方法最初没有正文,我发现实际添加代码的唯一方法是:

CtBehavior method = cl.getDeclaredBehaviors()[0];
method.setBody("System.out.println(\"Called.\");");
Run Code Online (Sandbox Code Playgroud)

注入本身可以工作,但是一旦加载库就说系统已经有代码,系统就会失败.

我宁愿不使用任何预制工具进行呼叫跟踪,因为我需要为用户格式化和打印列表.有办法处理这个吗?如果没有,是否有某种方法可以在另一个类中找到对OpenGL方法的所有调用,并追加对跟踪器类的附加调用?

Gui*_*one 1

With Javassist, is there any way to inject code into a native method?
Run Code Online (Sandbox Code Playgroud)

从未尝试过,但我并不惊讶它不起作用。本机代码是-本机的。它是一堆与 Java 字节码无关的特定于平台的位。Javassist 是关于 Java 字节码的。

您是否考虑过使用基于代理的 AOP?查看 http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies

我并不建议您在程序中实际使用 Spring,但它可能会给您一些如何解决问题的想法。我认为基于代理的 AOP 可能适合您的原因是您无需考虑基于 OpenGL 的类,它只使用正常的本机方法。您生成一个纯 Java 代理类,但具有与原始类相同的方法。您可以调用代理类上的方法,其中包含所需的呼叫跟踪代码,并使用其本机方法调用“普通对象”上的相应方法。

Spring 的文档说他们 在幕后使用 JDK 动态代理或CGLIB 。所以...我认为您可以直接使用其中一种技术来替代您的 javassist 解决方案。

希望这可以帮助。

[更新]

在上面的文本中,我认为您正在谈论您编写的一个主要具有实例方法的类。如果你谈论的是包装整个 OpenGL API,主要是静态方法,那么 AOP 代理方法就没那么有吸引力了。你有多想这么做?你可以:

  • 创建一个自定义类 - 具有工厂方法的单例类。您的单例类包装了整个 OpenGL API。没有记录/跟踪代码。只是对 API 的赤裸裸的调用。
  • 修改整个应用程序中的每个调用以使用包装器,而不是直接调用 OpenGL

此时,您已经拥有一个与您现在的应用程序完全一样的应用程序。

现在增强单例类的工厂方法,以返回除了 OpenGL 调用之外不执行任何操作的简单实例,或者返回一个 CGLIB 生成的代理,该代理记录每个方法。现在,您的应用程序可以在生产模式(快速)或跟踪模式下运行,具体取决于某些配置设置。

如果你想放弃并继续前进,我完全理解:)