Новичок в JNI. Я пытаюсь вызвать API-интерфейсы Element::getChild и Element::getChildText (java org.jdom.Element), чтобы получить номер версии системы, которая хранится в файле «settings.xml». Этот файл xml заархивирован в файле JAR. Предполагая, что корневой элемент доступен, вот что я делаю:
jstring fileNameStr = env->NewStringUTF("settings.xml");
jobject rootElement = env->CallStaticObjectMethod(a_class, xmlRootElement_mid, fileNameStr);
jclass cls_element = env->FindClass("org/jdom/Element");
/*get method ID for getChild() & getChildText() */
jmethodID getChild_mid = env->GetMethodID(cls_element, "getChild", "(Ljava/lang/String;)Lorg/jdom/Element;");
jmethodID getChildText_mid = env->GetMethodID(cls_element, "getChildText", "(Ljava/lang/String;)Ljava/lang/String;");
jstring aboutStr = env->NewStringUTF("about");
jobject about = env->CallStaticObjectMethod(cls_element, getChild_mid, aboutStr); ---> Seg Faults!!!
В принципе, я хочу сделать Java-эквивалент этого:
In Java:
import org.jdom.Element;
...
Element element = SomeMethodToReadXmlFile("settings.xml");
version = element.getChild("about").getChildText("version"); <---- works
Как мне это сделать?
@Michael Можете ли вы привести пример, как это должно называться?
Для статических методов: используйте GetStaticMethodID, а затем CallStatic<Type>Method с jclass в качестве первого аргумента. Например, методы: используйте GetMethodID, а затем Call<Type>Method с jobject в качестве первого аргумента.
@Майкл - большое спасибо! Получил это работает. Напишу ответ - может кому поможет.




Используя JNI, вот что сработало для меня, использующее org.jdom.Element. Мой файл settings.xml выглядит так:
<?xml version = "1.0">
<settings>
<about>
<version>1.0</version>
</about>
</settings>
JNI С++:
jstring fileNameStr = env->NewStringUTF("settings.xml");
// assuming xmlRootElement_mid is known
jobject element_obj = env->CallStaticObjectMethod(a_class, xmlRootElement_mid, fileNameStr);
jclass cls_element = env->FindClass("org/jdom/Element");
/*get method ID for getChild() & getChildText() */
jmethodID getChild_mid = env->GetMethodID(cls_element, "getChild", "(Ljava/lang/String;)Lorg/jdom/Element;");
jmethodID getChildText_mid = env->GetMethodID(cls_element, "getChildText", "(Ljava/lang/String;)Ljava/lang/String;");
jstring jstr = env->NewStringUTF("about");
element_obj = env->CallObjectMethod(element_obj, getChild_mid, jstr)
jstr = env->NewStringUTF("version");
jstring version_str = (jstring)env->CallObjectMethod(element_obj, getChildText_mid, jstr);
//Convert to std::string
std::string version_std_str;
if (version_str)
{
const char *c = env->GetStringUTFChars(version_str, 0);
version_std_str = std::string(c);
env->ReleaseStringUTFChars(version_str, c);
}
std::cout << version_std_str << std::endl
Выходы:
1.0
Почему вы используете
CallStaticObjectMethodиcls_element? Судя по вашему Java-коду,getChild— это метод экземпляра, а не метод класса.