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

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

07.02.2014, 23:00. Показов 1584. Ответов 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,705
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,705
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,705
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,705
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,705
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,705
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
Ответ Создать тему
Новые блоги и статьи
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3, Box2D, FreeType и SDL3_ttf из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru