2011-03-16 63 views
3

我有C++代碼調用返回對象的Java方法:JNI CallObjectMethod擰緊堆棧框架?

virtual bool OnGetData(sf::SoundStream::Chunk& data) { 
    jobject jchunk = env->CallObjectMethod(binding, JSoundStream::m_getData); 
    if(jchunk) { 
      //... some processing code will go here in the future 
      return true; 
    } 
    return false; 
} 

此方法在於C++類,其中binding是一個有效的全局Java對象引用和JSoundStream::m_getData的內部被以下方法的方法ID內下面的Java類:

public class TestStream extends JSoundStream { 
    [...] 

    @Override 
    public Chunk getData() { 
     return null; //testing 
    } 
} 

隨機獲得JVM內部訪問衝突時方法由C++叫。有時候它可以正常工作,有時我會遇到訪問衝突。刪除CallObjectMethod行不會導致一行,所以它必須是訪問衝突的來源。爲調試目的插入printfs使得訪問衝突的可能性更大。這對我來說是一個鐘聲:我非常確定有什麼東西在搞亂堆棧框架。

現在的問題是:什麼可能會搞砸堆棧框架?我找不到任何可疑的東西。它必須與對象方法調用有關,因爲刪除它可以消除任何問題。我的C++代碼是使用__cdecl調用約定(它是鏈接到我正在使用的密鑰庫所需的)編譯的,而JNI方法使用__stdcall,但對於我所知道的編譯器(MSVC++ 2008 Express)應該注意它並照顧「轉換」,所以我懷疑這是問題所在。如果是這樣,我將如何解決這個衝突?如果不是,那是什麼?

回答

1

這可能是您正在使用的env指針。您必須通過調用jvm->AttachCurrentThread(&env);來將JVM附加到當前線程,其中jvm指針已被緩存。