JNI CallObjectMethod портит кадр стека? - PullRequest
3 голосов
/ 16 марта 2011

У меня есть код 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-класса:

public class TestStream extends JSoundStream {
    [...]

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

I случайным образом получает нарушения доступа внутри JVM, когда этот метод вызывается из C ++.Иногда это просто отлично работает, иногда я получаю нарушение прав доступа.Удаление строки CallObjectMethod никогда не приведет к ее возникновению, поэтому оно должно быть источником нарушений доступа.Вставка printfs в целях отладки повышает вероятность таких нарушений доступа.Это звучит как колокол для меня: я почти уверен, что что-то портит кадр стека.

Вопрос теперь в следующем: что может испортить кадр стека?Я не могу найти ничего подозрительного.Он должен иметь какое-то отношение к вызову метода объекта, потому что его удаление избавляет от любых проблем.

Мой код C ++ скомпилирован с использованием соглашения о вызовах __cdecl (которое требуется для ссылки на библиотеку ключейЯ использую), а методы JNI используют __stdcall, но, насколько мне известно, компилятор (MSVC ++ 2008 Express) должен знать об этом и заботиться о «преобразовании», поэтому я сомневаюсь, что это проблема.Если это так, как бы я решил этот конфликт?Если нет, то что?

1 Ответ

1 голос
/ 08 июня 2012

Возможно, вы используете указатель env.Вы должны подключить JVM к текущему потоку, вызвав jvm->AttachCurrentThread(&env);, где указатель jvm был кэширован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...