2012-12-11 24 views
-1

我們應該有什麼樣的東西不是做JNI調用嗎?這些是什麼?
例如,我需要使用一個C++庫,它可以實現阻塞和非阻塞I/O調用。
在這些情況下,我應該注意哪些警告?我也知道,腳本提供了相同的功能(但不確定實際的腳本語言)。這是一個更好的選擇(從Java調用腳本)?如果是,爲什麼?有沒有什麼是通過JNI做壞主意?

回答

1

JNI不會限制你可以在很多方面,做什麼,除了當您使用GetPrimitiveArrayCritical and GetStringCritical

調用GetPrimitiveArrayCritical後,本地代碼不應該 運行的時間過長它調用 ReleasePrimitiveArrayCritical前。我們必須將函數對 中的代碼視爲在「關鍵區域」中運行。在關鍵 區域內,本機代碼不得調用其他JNI函數或調用任何可能導致當前線程阻塞並等待另一個Java線程的系統調用。 (例如,當前線程不能調用一個 流中讀取寫入另一個Java線程。)

否則你幾乎可以自由地做你想做什麼都,酒吧的事情,怎麼改JVM和操作系統交互(如replacing the JVM signal handlers)。

你還問你是否應該運行腳本,而不是直接調用本地函數。如果您不知道C++庫究竟會做什麼,那麼執行外部過程會更安全,但它也不太方便(您需要建立通信方式),並且可能比在同一過程中進行調用要慢。

+0

我對在引擎蓋下阻塞I/O或非阻塞(例如'select'調用)的情況感興趣 – Cratylus

+0

文件I/O應該是安全的。 – Joni

1

從我個人的經驗來看,糟糕的想法是使用大於平常的第三方庫作爲黑箱,不知道它究竟發生了什麼。線程,I/O,硬件API訪問,長時間運行的JNI調用,最糟糕的是,自定義內存管理(而不是標準庫malloc/free)。毛病可能會發生,包括JVM報告內存泄漏和奇怪位置的異常,和/或莫名其妙的崩潰。有了這樣一個庫(巨大的OpenGL引擎),我們不得不剖析並採用外部過程方法。它通過命名管道進行交流,速度驚人。要採取的措施:始終知道原生lib在底層做了什麼,這對於JAR來說並不是那麼必要。

+0

我明白你在說什麼。但在我的情況下,庫很小,我知道它的功能(阻塞/非阻塞IO到文件) – Cratylus

+1

好的非阻塞IO表明將有一個線程產生本機回調,從中你將毫無疑問想要回調給JVM。所以我建議閱讀'AttachCurrentThread'和'JNIEnv'的生命週期。以後你會爲自己節省一些嚴重的問題。 –

相關問題