Форум программистов, компьютерный форум, киберфорум
Java
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,702

Обсуждение машинно-зависимых методов, как они представлены у Шилдта "Java. Полное руководство" (необходимо знание C/C++)

07.02.2014, 23:00. Показов 1558. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
А представлены они так, ребята, что ни за что не скомпилятся и работать не будут.

Вот сам код машинно-зависимого метода, взят из книги:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <jni.h> 
#include "NativeDemo.h" 
#include <stdio.h> 
 
JNIEXPORT void JNICALL Java_NativeDemo_test(JNIEnv *env, jobject obj) 
{ 
  jclass cls; 
  jfieldID fid; 
  jint i; 
 
  printf("Starting the native method.\n"); 
  cls = (*env)->GetObjectClass(env, obj); 
  //Тут тоже код, но я его опустил для простоты. В Си такое допускается
}
Так вот, он не скомпилится и работать не будет. Посмотрим, что зе переменная такая env- а она представляет из себя указатель на JNIEnv; JNIEnv, в свою очередь- структура (файл jni.h идёт вмсте с книгой):

C++
1
2
3
4
5
6
7
8
9
//jni.h
//код разный
//...
typedef JNIEnv_ JNIEnv;
//код разный
//...
struct JNIEnv_ {
//код разный
//...
То есть в функцию передаётся указатель на структуру и вызывается член этой структуры:
C++
1
(*env)->GetObjectClass(env, obj);
Вот это-то и неправильно. Надо так (кстати, работает, проверено):
C++
1
env->GetObjectClass(env, obj);
Или на худой конец
C++
1
(*env).GetObjectClass(env, obj)
;

Но это нежелательный способ, ибо надо позаботиться о конструкторе структуры JNIEnv, а оно нам даром не надо.

Вот, собсно ПЕРВАЯ ошибка. Хотелось бы знать, может я излишне самоуверен и ошибаюсь? ТОгда был бы рад поправкам.

Не по теме:

Написал бы в раздел C++, но там не поймут. Кому там какое дело до java? А раздела java/C++ нет.

0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.02.2014, 23:00
Ответы с готовыми решениями:

Synchronized. Не работает пример из книги Шилдта «Java. Полное руководство»
Я нашёл ошибку в книге Герберта Шилдта «Java. Полное руководство». Это не задача из книги. Это опячатка. Там при описании синхронизации...

Книга Г. Шилдта Полное руководство С#
Ребят, у кого есть в продаже подержанная книга Г. Шилдта Полное руководство С#? хотел бы приобрести, в магазах разоришься по таким ценам...

упражнения к книге Шилдта C# Полное руководство
Читаю книгу Герберта Шилдта Полное руководство C# 4.0 Читать не сложно и разжевывается все вполне хорошо и доступно, но вот хотелось-бы еще...

13
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
08.02.2014, 00:20
Цитата Сообщение от kravam Посмотреть сообщение
ТОгда был бы рад поправкам.
вы забыли что в JNI не только С++ но и голый C допустим, гляньте на мой примерчик, там оба стиля
https://www.cyberforum.ru/blog... g1384.html
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,702
08.02.2014, 00:30  [ТС]
Вот ВАШ пример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// C стиль вызовов
    jsize stringCount = (*env).GetArrayLength(ja);
    jclass retclazz = (*env).FindClass("java/util/Vector");
    jobject ret = (*env).NewObject(retclazz, (*env).GetMethodID(retclazz, "<init>", "()V"));
// C++ стиль вызовов
    jclass myclazz = env->FindClass("MyClass");
    for (int i = 0; i < stringCount; i++) {
        jstring str = (jstring) env->GetObjectArrayElement(ja, i);
        jobject myobj = env->NewObject(myclazz, env->GetMethodID(myclazz, "<init>", "()V"));
        jmethodID setS = env->GetMethodID(myclazz, "setS", "(Ljava/lang/String;)V");
        env->CallVoidMethod(myobj, setS, str);
        jmethodID add = env->GetMethodID(retclazz, "add", "(Ljava/lang/Object;)Z");
        env->CallVoidMethod(ret, add, myobj);
    }
    return ret;
И? Ни в Cи стиле, ни в С++ стиле я не вижу, как у Шилдта:
C++
1
(*env)->FindClass("java/util/Vector");
А вижу разыменование указателя (способ, отвергнутый мной как трудоёмкий)
C++
1
(*env).FindClass("java/util/Vector");
Либо то, что предложил я:
C++
1
env->GetObjectArrayElement(ja, i);
В общем, зачем пример дан- непонятно. Вопрос открыт.
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
08.02.2014, 00:52
Цитата Сообщение от kravam Посмотреть сообщение
я не вижу, как у Шилдта:
в общем то шилдт говно книга,
пример дан чтобы показать как мы (программисты java) пользуемся нативными вызовами,
вы меня извините я не глянул на ник - кому отвечаю, очень об этом сожалею, впредь буду внимательнее...
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,702
08.02.2014, 01:04  [ТС]
Цитата Сообщение от mutagen Посмотреть сообщение
в общем то шилдт говно книга,
очень может быть.

++++++++++++++++++++++++++++++++++++++++ +

Цитата Сообщение от mutagen Посмотреть сообщение
пример дан чтобы показать как мы (программисты java) пользуемся нативными вызовами,
да? А я грешным подумал, что пример дан, чтобы показать мне использование вполне себе корректного голого стиля Си, которого я, по неумению своему, не углядел у Шилдта. И разрешить тем самым мой вопрос:
Цитата Сообщение от mutagen Посмотреть сообщение
вы забыли что в JNI не только С++ но и голый C допустим, гляньте на мой примерчик, там оба стиля
++++++++++++++++++++++++++++++++++++++++ +

Цитата Сообщение от mutagen Посмотреть сообщение
вы меня извините я не глянул на ник - кому отвечаю, очень об этом сожалею, впредь буду внимательнее...
да пожалуйста. Если вдруг будет что сказать по существу, приходите. Вопрос открыт.
0
08.02.2014, 02:49

Не по теме:

Что за ужасы тут происходят? Объясните мне что это

0
08.02.2014, 22:29

Не по теме:

Цитата Сообщение от Recreate Посмотреть сообщение
Не по теме:
Что за ужасы тут происходят? Объясните мне что это
да просто kravam, развлекает (но иногда шибко напрягает) :)

0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,702
09.02.2014, 02:01  [ТС]

Не по теме:

Цитата Сообщение от Recreate Посмотреть сообщение
Что за ужасы тут происходят? Объясните мне что это
А это, дружок, вопрос по программированию. Иногда тут такое имеет место быть.


Короче, тут не то, чтобы всё плохо, но как-то неопределённо. У Шилдта, в двух изданиях одна и та же ошибка. Пытался смотреть другую литературу- сведений кот наплакал. Так, у Брюса Эккеля материала по родным методам нет. У Хорстманна Кея, Корнелла Гари нет. У Арнольда и Гослинга есть. Но там тоже синтаксис Си смешной какой-то. Заголовочные файлы включаются так <<>>:, обращение к полям структуры такое->>; не знаю, прямо, что и делать. Пока условимся, что Шилдт ошибся, чай, я не вчера начал C/C++ учить. Тем более, что если Шилдтовский вариант исправить, всё заработает на ура:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
extern "C"
JNIEXPORT void JNICALL Java_NativeDemo_test(JNIEnv *env, jobject obj) 
{ 
  jclass cls; 
  jfieldID fid; 
  jint i; 
// 
  printf("Starting the native method.\n"); 
  cls = env->GetObjectClass(obj); 
  fid = env->GetFieldID(cls, "i", "I"); 
//// 
  if(fid == 0) { 
    printf("Could not get field id.\n"); 
    return; 
  } 
// 
  i = env->GetIntField(obj, fid); 
  printf("i = %d\n", i); 
  env->SetIntField(obj, fid, 2*i); 
  printf("Ending the native method.\n"); 
}
Ну и в статьях, подобных этой Тоже видим какой надо синтаксис.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
09.02.2014, 16:53
kravam, возможно переводчик книги или русский редактор решил, что так (*env)-> будет лучше. Подобное часто встречается в книгах буржуйских авторов, которые выпускались нашими изданиями.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,702
09.02.2014, 16:58  [ТС]
Но это же прямо смех какой-то! Вы согласны, что это ошибка? Я просто всё ещё не уверен в своём решении забраковать Шилдтовский (или переводческий или редакторский) вариант! Всяко бывает в жизни. И если это так, почему после седьмого издания никто не указал на ошибку? Получается, я один книги и читаю.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
09.02.2014, 20:10
Лучший ответ Сообщение было отмечено kravam как решение

Решение

Цитата Сообщение от kravam Посмотреть сообщение
Вы согласны, что это ошибка?
kravam, вы же не первый день на С++ пишите, конечно ошибка.

Добавлено через 3 часа 9 минут
Ради интереса погуглил исходники к этой книге. Нашел, там код такой же, поэтому действительно странно, что ошибка остается не замеченной.

Итак, попробуем разобраться, нашел на вражеской вики такие примеры
С++
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//C++ code
extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
  (JNIEnv *env, jobject obj, jstring javaString)
{
    //Get the native string from javaString
    const char *nativeString = env->GetStringUTFChars(javaString, 0);
 
    //Do something with the nativeString
 
    //DON'T FORGET THIS LINE!!!
    env->ReleaseStringUTFChars(javaString, nativeString);
}
С
C
1
2
3
4
5
6
7
8
9
10
11
12
/*C code*/
JNIEXPORT void JNICALL Java_ClassName_MethodName
  (JNIEnv *env, jobject obj, jstring javaString)
{
    /*Get the native string from javaString*/
    const char *nativeString = (*env)->GetStringUTFChars(env, javaString, 0);
 
    /*Do something with the nativeString*/
 
    /*DON'T FORGET THIS LINE!!!*/
    (*env)->ReleaseStringUTFChars(env, javaString, nativeString);
}
мы видим, что в С++ коде env используется, как ожидается, а в С коде как в первом посте.

Интересно, что же это такое.
Лезем в jni.h и вуаля, тайна раскрыта
C++
1
2
3
4
5
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endif
Для С++ JNIEnv это структура, а JNIEnv* это указатель на структуру. А вот для С JNIEnv это указатель, поэтому JNIEnv* получается указатель на указатель, т.е. синтаксис
C
1
(*env)->GetObjectClass(env, obj);
абсолютно правильный для языка С
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,702
09.02.2014, 20:40  [ТС]
Цитата Сообщение от Kastaneda Посмотреть сообщение
нашел на вражеской вики такие примеры
Так можно было меня попросить, у меня есть jni.h. Мне вот только одно непонятно, это я видел:

C++
1
2
3
4
5
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endif
Я совсем не обратил внимания на
C++
1
typedef const struct JNINativeInterface_ *JNIEnv;
. Конечно, это неправильно, не обращать на неё внимания. Но я не знаю, как с этим работать.
C++
1
#ifdef __cplusplus
я читаю так: "Если макрос __cplusplus определён, то и т.д." Но это только слова понятны, а смысл нет, Ибо я не знаю,

1) То ли это я его должен определять, то ли кто другой. Кто? (Тот же nixman, который лепит компиляторы?)
2) В каком месте? Предполагаю, что где-то из хидеров он есть. Мне хидеры править?
3) А самое главное- что даст? Ну, допустим, мне удастся как-нибудь куда-нибудь запихать строчку
C++
1
#undef __cplusplus
Ага, так это что значит? Командная строка у меня g++, расширение фала-сырца *.cpp. Оттого, что я деопределю
C++
1
__cplusplus
, C++сный код Сишным не станет ведь. Поэтому, что мне дадут манипуляции с макросом __cplusplus, (имею ввиду как произойдёт изменение языка с С++ на Си) непонятно.

Тема, конечно, для отдельного разговора. С авторскими (своими то бишь, так, как они описаны у Evg) макросами я разобрался ещё худо-бедно. А вот с поставляемыми (да ещё с компилятором) не научился.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
09.02.2014, 21:18
Цитата Сообщение от kravam Посмотреть сообщение
Так можно было меня попросить, у меня есть jni.h
jni.h есть у всех, у кого установлен jdk )
Цитата Сообщение от kravam Посмотреть сообщение
То ли это я его должен определять, то ли кто другой.
компилятор сам определяет этот макрос.
Если хочешь использовать С++ вариант JNIEnv - компилируй g++, если сишный - компилируй gcc.

Добавлено через 7 минут
Цитата Сообщение от kravam Посмотреть сообщение
Кто?
из стандарта С++
16.8 Predefined macro names
1 The following macro names shall be defined by the implementation:
__ cplusplus
The name __ cplusplus is defined to the value [tbd] when compiling a C ++ translation unit*.

* It is intended that future versions of this standard will replace the value of this macro with a greater value. Non-conforming compilers should use a value with at most five decimal digits.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,702
24.02.2014, 18:19  [ТС]
По предопределённым макросам, в частности, __cplusplus здесь всё подробно разобрано
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.02.2014, 18:19
Помогаю со студенческими работами здесь

К какой книге переходить после "C# 4.0 полное руководство" Шилдта
Посоветуйте к какой лучше книге переходить после &quot;C# 4.0 полное руководство&quot; Шилдта.Спасибо.

Даст ли базовые знания изучение Герберта Шилдта "C# 4.0. Полное руководство"
Подскажите новичку: Герберт Шилдт &quot;C# 4.0. Полное руководство&quot; - изучив этот материал я буду знать язык на базовом уровне? И что вы...

Строковые литералы, Шилдт Г. - Java 8. Полное руководство - 2015
Шилдт Г. - Java 8. Полное руководство 2015г. страница 86 : &quot;Управляющие символы и восьмеричная или шестнадцатеричная форма записи,...

Java и знание английского. Необходимо ли?
Добрый день! Хотел бы спросить: все ли вы, Java-программисты, хорошо владеете английским языком? Настолько ли он необходим для изучения, и...

C++ и Java Development - где необходимо знание обоих языков
в какой области применимо знание и С++ и java(без знания всяких html css php итд).


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru