2010-06-22 53 views
4

我有一個與數據庫交談的C++層,此C++層執行一個新的SomeObject()並將其返回給java。jni和在java中使用C++ new'ed對象

什麼時候可以安全地通過我乾淨的jni調用刪除SomeObject。我可以刪除一旦Java有返回的對象,或者我需要複製對象,然後刪除?

+1

如何將C++對象直接返回給Java?你不必使用JNI環境來實例化適當的Java對象嗎? – Daff 2010-06-22 17:28:35

+0

是的,這就是我想的,我在一個新的地方,我看着這個不是代碼,我不確定所有的東西都已經到位。 – arinte 2010-06-22 17:30:49

回答

9

由於DAFF寫道,你不能「返回一個C++對象到Java」,但你可以做的是返回對象的地址,作爲一個長:

jlong obj_ptr = reinterpret_cast<jlong>(&obj); 

你應該確保地方在根標頭中,jlong​​的大小足以容納指針(它通常應該是,因爲Java long是64位寬)。我使用Boost的靜態斷言進行檢查:

#include <boost/static_assert.hpp> 
BOOST_STATIC_ASSERT(sizeof(jlong)>=sizeof(void *)); 

,只要是需要它(或它的數據)的C++對象應該生活,無論是在Java或C++ - 無論如何,它不能被Java刪除直。當你確定你可以安全地刪除它時,你可以從java中調用另一個JNI調用,傳遞一個long值,並將它轉換爲reinterpret_cast<SomeObject *>(the_jlong_value)的適當指針,然後刪除它。當然,你必須手動刪除它,JVM完全不知道它的存在,並且所有手動內存管理的注意事項都適用...

+4

不再需要我離開了可怕的公司,我需要這樣做。 – arinte 2010-12-13 21:02:18

+0

在上面的例子中,obj必須在全局範圍內聲明。否則它可能會返回堆棧地址,儘快包含函數返回該地址是無效的。 – 2016-05-29 20:23:45

+0

您不是指「在全局範圍內聲明」。你的意思是「分配在堆上,而不是在堆上」。 – 2016-05-30 06:11:24