JNI CallObjectMethod搞砸堆栈框架?

时间:2011-03-16 07:56:45

标签: java c++ stack java-native-interface

我有C ++代码调用一个返回对象的Java方法:

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是以下Java类中以下方法的方法ID:

public class TestStream extends JSoundStream {
    [...]

    @Override
    public Chunk getData() {
        return null; //testing
    }
}
当从C ++调用该方法时,随机在JVM内部获取访问冲突。有时它只是工作正常,有时我会遇到访问冲突。删除CallObjectMethod行永远不会导致一行,因此它必须是访问冲突的来源。插入printfs以进行调试可能会更有可能导致这些访问冲突。这对我来说是一个响铃:我很确定有什么东西搞砸了堆栈框架。

现在的问题是:什么可能会搞砸堆栈框架?我找不到任何可疑的东西。它必须与对象方法调用有关,因为删除它可以解决任何问题。

我的C ++代码是使用__cdecl调用约定编译的(这是链接到我正在使用的密钥库所必需的),而JNI方法使用__stdcall,但是对于我所知道的编译器(MSVC ++ 2008 Express)应该注意它并处理“转换”,所以我怀疑这是问题所在。如果是,我将如何解决这一冲突?如果不是,那是什么?

1 个答案:

答案 0 :(得分:1)

可能是您正在使用的env指针。您必须通过调用已缓存jvm->AttachCurrentThread(&env);指针的jvm将JVM附加到当前线程。