JNI: Данный jobject, получите его припрятавший про запас метод

На Яве у меня есть интерфейс:

public interface I {...}

объявление функции пустота f() , и некоторые классы:

public class A implements I {...}
public class B implements I {...}
public class C implements I {...}
...

Я часто вызываю родную функцию:

public native void nativeFunc(I obj);

В C++ я получаю a

jobject jobj

Цель состоит в том, чтобы звонить

jobj.f();

не идя каждый раз через цепь

cls = jenv->GetObjectClass(jobj);           (1)
mid = jenv->GetMethodID(cls, "f", "()V");   (2)
jenv->CallVoidMethod(jobj, mid);            (3)

I can't seem to cache mid between native calls. As another suggestion, I could start with line (1), then use a cached map . However, this probably won't work, too, since jclass references might differ for the same class.

Там кто-либо оптимизирует решение?

0
nl ja de

2 ответы

Одно из решений, о которых я могу думать, состоит в том, чтобы припрятать классы про запас A, B, C... их jclass ссылки в любую структуру данных (множество, список, безотносительно; карта не ускорение здесь). Давайте назовем эту структуру Хранением. Тогда я мог оптимизировать шаг (2) и иметь следующую цепь:

(1) ... (obtain jcls)
(2) for(jclass jclsStored : Storage) {
        if(IsSameObject(jcls, jclsStored))
        {
            mid = ...;
            classFound = true;
        }
    }
    if(!classFound)
        Storage.add(necessary info);
(3) ...            

Т.е. Я использую JNI

IsSameObject()

функционируйте, чтобы обойти отличающийся jclass ценности для того же самого класса. Если , IsSameObject() быстр, то это делает оптимизацию.

0
добавлено

В зависимости от природы вашей программы и количества осуществления классов 'взаимодействуют I', а также количество доступных погрузчиков класса (который может умножить количество классов), можно решить создать глобальную ссылку на те классы

jclass globalRefCls = jni->NewGlobalRef(localRefCls);

Тогда можно припрятать про запас те случаи и jmethodID в карте для более позднего использования.

ОБНОВЛЕНИЕ

After the talk in the comments, I re-read your requirements.
As long as you get a jobject every time, you need to get the jclass out anyway, your map can also be map where the string is the descriptor of the class.

Каждый раз вы получаете jobject, извлекаете jclass, и спрашивает, поскольку это - имя (можно припрятать метод java/lang/Class getName про запас).

You can also create this cache up front it you'd like, since you know which objects to expect (the ones implement I)

Однако я предполагаю, что это не будет столь же эффективно как проверка IsSameObject.

0
добавлено
Чен, если вы предлагаете прятать классы про запас A, B, C... их jclass ссылки, тогда это won' t работа, как я написал в конце своего вопроса. Кэширование любых ссылок (или местный или глобальный) в карте бесполезно, так как различные ссылки на тот же самый Явский класс/объект могли бы отличаться по ценностям!
добавлено автор Alexander Shmuratko, источник
Читайте два параграфа, начинающиеся со "Всех методов JNI, принимают..." под "Местными и Глобальными Ссылками" часть Android подсказки JNI.
добавлено автор Alexander Shmuratko, источник
I' m боящийся это действительно относится к классам. I' ve просто запускают тест. I' ve, которым позвонили, jclass c0 = jenv-> GetObjectClass (jobj); Затем I' ve сделал 100 требованиями jclass c1 = jenv-> GetObjectClass (jobj); Сравнение (c0 == c1) дает ложный (вероятно, для всех 100 случаев), и IsSameObject (c0, c1) дает верный. Этот тест сделан в одной родной функции, прямо после того, как это начнется как один блок кода.
добавлено автор Alexander Shmuratko, источник
Дело в том, что it' s ОДИН объект класса, не два, - но it' s много ссылок на тот класс, отличающийся в стоимости, созданной различными звонками в GetObjectClass() для того же самого объекта. It' s, как JNI работает...
добавлено автор Alexander Shmuratko, источник
То, что я хочу, не то, что вы думаете. Я хочу припрятать про запас не один класс, но многих - любой Явский класс ( A, B, C... ), который мог осуществить интерфейс я . Эти классы будут много раз повторяться, это - то, почему я хочу припрятать их про запас, но они - несколько, не один. Таким образом, я должен сначала получить object' s класс и затем получить it' s припрятавшая про запас информация.
добавлено автор Alexander Shmuratko, источник
Чен, спасибо за ваши усилия помочь. Я думал о получении названия класса и создания его ключ для карты. Однако это намного более отнимающее много времени: 1) цепь Object.getClass() .getName() , и я can' t тайник очень здесь, это уже хуже, чем езда на велосипеде througn Хранение в местном масштабе; 2) Даже после получения jstring с именем я должен звонить GetStringUTFChars() , чтобы восстановить случайную работу константы* ... Слишком много работы.
добавлено автор Alexander Shmuratko, источник
То, почему вы думаете, пряча глобальную ссылку про запас на класс, может отличаться? Вы используете VM, который может разгрузить классы? или VM, который загружает многократные классы через различные погрузчики класса?
добавлено автор Chen Harel, источник
Этот doesn' t относятся к jclass начиная с вас can' t создают два Объекта класса того же самого типа, не используя различные погрузчики класса.
добавлено автор Chen Harel, источник
У jclass не будет того же самого адреса (именно это == проверяет между указателями как jclass/jobjects), и вы shouldn' t заботятся об этом также. То, что вы хотите, является действительным jclass, который может использоваться в функциях JNI позже в вашей программе и делая его глобальной ссылкой, это будет.
добавлено автор Chen Harel, источник
Перечитайте свои требования, обновил мой ответ.
добавлено автор Chen Harel, источник
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

pro.cxx
pro.cxx
3 049 участник(ов)

C/C++ chat 0. Простые вопросы, лабы и о IDE — в чат новичков @supapro 1. Не хамим, не переходим на личности, не вбрасываем утверждения без доказательств 2. No Ads, offtop, flood Объявления о вакансиях и евенты - в лс @AlexFails https://t.me/ProCxx/259155

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

supapro.cxx
supapro.cxx
1 925 участник(ов)

Чат для тех, кто немного знает C++, простые вопросы по реализации, синтаксису и ide – сюда, а для другого есть: /Главный чат по серьезным вопросам — @ProCxx /Чат по обсуждению всего — @fludpac

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

C++ Russia
C++ Russia
384 участник(ов)

Сообщество разработчиков C++ в Telegram.

cxx.Дискуссионная
cxx.Дискуссионная
298 участник(ов)

это не двач, общайтесь вежливо; разговор на почти любые темы; Не согласны с баном? В лс @AlexFails, @ivario

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async

C++ для маленьких и тупых
C++ для маленьких и тупых
105 участник(ов)

Лоу левел (по среднему IQ участников) чатик ExtremeCode @extremecode Флудилка @extremecode_rest