2011-03-16 66 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指针已被缓存。