我有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)應該注意它並照顧「轉換」,所以我懷疑這是問題所在。如果是這樣,我將如何解決這個衝突?如果不是,那是什麼?