2012-09-30 41 views
3

使用Javassist,有什麼方法可以將代碼注入本機方法?在這種情況下,我試圖讓我的遊戲中的OpenGL調用在調用時打印出他們的名字和值,但是當我假設添加了openGL dll代碼時,我所有的嘗試都遇到了錯誤。用javassist編輯本地方法類?

的方法看起來是這樣的:

public static native void glEnable(int paramInt); 

由於方法最初沒有身體,我發現實際添加的代碼的唯一方法是這樣的:

CtBehavior method = cl.getDeclaredBehaviors()[0]; 
method.setBody("System.out.println(\"Called.\");"); 

注入本身是可以工作的,但是一旦加載了庫說系統已經有代碼,系統就會失敗。

由於我需要爲用戶格式化並打印出列表,因此我寧願不使用任何預製工具進行通話跟蹤。有什麼辦法可以解決這個問題嗎? 如果沒有,是否有某種方法可以找到對另一個類中的OpenGL方法的所有調用,並將追加的調用追加到跟蹤器類?

回答

1
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動態代理或CGLIB。所以......我在想你可以直接使用這些技術中的一種來替代你的javassist解決方案。

希望這會有所幫助。

[更新]

在上面的文字我還以爲你在談論你所編寫的類,它主要有實例方法。如果您正在討論包裝整個OpenGL API(主要是靜態方法),那麼AOP代理方法不太吸引人。你想這樣做有多糟糕?您可以:

  • 創建一個自定義類 - 帶有工廠方法的單例類。你的單例類包裝整個OpenGL API。沒有日誌記錄/跟蹤代碼。只是對API的裸體調用。
  • 修改你的整個應用使用包裝的每一個電話,而無需調用OpenGL直接

在這一點上,你有工作就像你現在有什麼樣的應用程序。

現在,增強singleton類的工廠方法,以返回除OpenGL調用之外什麼都不做的基本實例,或者它可以返回記錄每種方法的CGLIB生成的代理。現在,您的應用可以在生產模式(快速)或跟蹤模式下運行,具體取決於某些配置設置。

我完全得到它,如果你想給這個了,繼續前進:)

+0

聽起來很有趣。有什麼好的方法來動態生成一個代理類,或者這將需要編輯我所有的代碼引用預製代理? – Felix

+0

那麼,我剛剛在http://markbramnik.blogspot.com/2010/04/cglib-introduction.html上找到了一個cglib教程,它會給你一個你將會得到什麼的想法。基於教程,我認爲答案是「是」,它會動態生成代理類。 –

+0

代理的生成是一回事,但這看起來像是要求我重寫遊戲中的每一行代碼,以生成代理並調用該代理,而不是OpenGL類。也許我需要一種不同的方法。有什麼方法可以找到所有對OpenGL方法的調用並追加一個跟蹤器類的調用? – Felix