使用Javassist,有没有办法将代码注入本机方法?在这种情况下,我试图让我的游戏中的OpenGL调用在调用时打印出他们的名字和值,但是当我假设添加了openGL DLL代码时,我的所有尝试都会遇到错误.
该方法看起来像:
public static native void glEnable(int paramInt);
CtBehavior method = cl.getDeclaredBehaviors()[0];
method.setBody("System.out.println(\"Called.\");");
注入本身可以工作,但是一旦加载库就说系统已经有代码,系统就会失败.
我宁愿不使用任何预制工具进行呼叫跟踪,因为我需要为用户格式化和打印列表.有办法处理这个吗?
如果没有,是否有某种方法可以在另一个类中找到对OpenGL方法的所有调用,并追加对跟踪器类的附加调用?
With Javassist,is there any way to inject code into a native method?
从未尝试过,但我并不感到惊讶它不起作用.本机代码是 – 本机代码.它是一堆与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动态代理或@L_301_2@.所以……我认为您可以直接使用这些技术之一来替代您的javassist解决方案.
希望这可以帮助.
[更新]
在上面的文本中,我以为你在谈论一个主要由实例方法编写的类.如果您正在讨论包装整个OpenGL API(主要是静态方法),那么AOP代理方法就不那么吸引人了.你有多想做这个?你可以:
>创建一个自定义类 – 一个带有工厂方法的单例类.您的单例类包装了整个OpenGL API.没有记录/跟踪代码.只是裸体调用API.
>修改整个应用程序中的每个调用以使用您的包装器,而不是直接调用OpenGL
此时,您的应用程序的工作方式与您现在的工作方式完全相同.
现在增强单例类的工厂方法,以返回除了OpenGL调用之外什么都不做的简单实例,或者它可以返回记录每个方法的CGLIB生成的代理.现在,您的应用可以在生产模式(快速)或跟踪模式下运行,具体取决于某些配置设置.
如果你想放弃并继续前进,我完全明白了:)