Forum: Diğer Konular RSS
C++ - Jni ile İlgili Anlam Veremediğim Bir Hata
İbrahim #1
Üye Eki 2015 tarihinden beri · 142 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: C++ - Jni ile İlgili Anlam Veremediğim Bir Hata
Selamün Aleyküm;

C++ ile Jni denemesi yapmak istedim, lakin hatalar peşimi bırakmıyor. İntenette herkesi Java'dan C/C++ kodları çağırıyor ama ben tam tersini yapıyorum: C++'dan Java kodu çağırıyorum. Yazdığım kodlar şöyle:

Code.java:
package com.xxx;
 
public class Code
{
  public void getMessage()
  {
    System.out.println("Hello World!");
  }
}

main.cpp:
#include <jni.h>
#include <iostream>
using namespace std;
 
int main(int argc, char* argv[])
{
  JavaVM* jvm;
  JNIEnv* env;
  JavaVMInitArgs jvm_args;
  JavaVMOption options[1];
 
  options[0].optionString = "-Djava.class.path=myclasses";
  jvm_args.version = JNI_VERSION_1_2;
  jvm_args.options = options;
  jvm_args.nOptions = 1;
  jvm_args.ignoreUnrecognized = JNI_TRUE;
 
  jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &jvm_args);
  if (res < 0)
  {
    cout << "Cannot create JVM!\n";
    exit(1);
  }
 
  jclass class_ = env->FindClass("com/xxx/Code");
  if (class_ == 0)
  {
    cout << "Code class not found!\n";
    exit(1);
  }
 
  jmethodID method_id = env->GetMethodID(class_, "getMessage", "()V");
  if (method_id == 0)
  {
    cout << "getMessage() method not found!\n";
    exit(1);
  }
 
  env->CallVoidMethod(class_, method_id);
 
  return 0;
}
Dosyalarımın dizinleri:
[Resim: https://i.stack.imgur.com/hJgB0.png]

Bu kodlardan aldığım hata şu: Code class not found!. İlginç olan ise dizinleri gösteren resimden de göreceğiniz üzere Code.java'nın myclasses/com/xxx dizini altında bulunmasına rağmen sınıfı bulamıyor, yani FindClass NULL döndürüyor. Bu kodları Oracle'ın sitesinden okuyarak yazdım.
Bu suali yabancı birçok forumda vs. sordum lakin hiç kimse kodlarda bir hata olduğunu söylemedi ve sonuca ulaşamadığım yanıtlar aldım. Code.java sınıfının normalde çalışıp çalışmadığını sordular, bu sınıfı QAndroidExtras modülü yardımıyla çağırdığımda çalıştı ama saf Jni ile çalışmıyor. Çünkü ne hikmetse sınıfı bulamıyor. Sınıfı bulamadığını bir istisna ile anladım:
Exception in thread "main" java.lang.NoClassDefFoundError: com/xxx/Code
Caused by: java.lang.ClassNotFoundException: com.xxx.Code
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f7ecb626304, pid=10848, tid=0x00007f7ecc138740
#
# JRE version: Java(TM) SE Runtime Environment (8.0_111-b14) (build 1.8.0_111-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.111-b14 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x6da304]  get_method_id(JNIEnv_*, _jclass*, char const*, char const*, bool, Thread*)+0x84
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/username/My Projects/build-JNIExample-Desktop_Qt_5_7_0_GCC_64bit-Debug/hs_err_pid10848.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
Press <RETURN> to close this window...
Bu sorun ile uğraşan oldu mu? Teşekkürler.
erdem (Moderatör) #2
Üye Tem 2009 tarihinden beri · 906 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
http://www.swig.org/tutorial.html

Dün gtkd'nin derlenmesini beklerken ben de buraya baktım. Bu kütüphane JNI kodu üretebiliyormuş.
İbrahim #3
Üye Eki 2015 tarihinden beri · 142 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Cevap için teşekkürler. Aslında yazdığım kodu Qt Creator ile şu parametreleri .pro dosyasına ekleyince kod derleniyor ama Class not found diyor:
INCLUDEPATH += /usr/lib/jvm/java-8-oracle/include
INCLUDEPATH += /usr/lib/jvm/java-8-oracle/include/linux
LIBS += -L/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/ -ljvm

Lakin aynı kodu terminalden şu komutla yapınca hata veriyor:
g++ -I/usr/lib/jvm/java-8-oracle/include -I/usr/lib/jvm/java-8-oracle/include/linux
-L/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so main.cpp -o main -std=c++11
Çıktı:
main.cpp: In functionint main()’:
main.cpp:17:27: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
   options[0].optionString = "-Djava.class.path=src/com/xxx";
                                     ^
/tmp/ccD42OEq.o: In function `main':
main.cpp:(.text+0x4c): undefined reference to `JNI_CreateJavaVM'
collect2: error: ld returned 1 exit status 
Bu nasıl birşey anlamadım gitti.
erdem (Moderatör) #4
Üye Tem 2009 tarihinden beri · 906 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İbrahim:
/tmp/ccD42OEq.o: In function `main':
main.cpp:(.text+0x4c): undefined reference to `JNI_CreateJavaVM'
collect2: error: ld returned 1 exit status 
Bu nasıl birşey anlamadım gitti.

Burada bağlayıcı jni kütüphanesini bulamadığını söylüyor. Bunun için -l seçeneği ile kütüphaneyi eklemek gerekiyor.

Örneğin -L/lib/jvm/java-8-oracle/jre/lib/amd64/server/ -llibjvm şeklinde (ya da lib olmadan -ljvm de) olabilir.

Yanlış hatırlamıyorsam büyük -L kütüphanenin olduğu dizini belirtiyor.
İbrahim #5
Üye Eki 2015 tarihinden beri · 142 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Teşekkürler lakin yine aynı:
g++ -I/usr/lib/jvm/java-8-oracle/include -I/usr/lib/jvm/java-8-oracle/include/linux
-L/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/ -ljvm main.cpp -o main -std=c++11
-llibjvm'yi de denedim o da aynı hatayı veriyor.
İbrahim #6
Üye Eki 2015 tarihinden beri · 142 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Selamün Aleyküm;

Sorunu çözdüm! Meğersem kullandığım tümleşik geliştirme ortamı Qt Creator projeyi farklı bir build-*** klasörü oluşturarak derliyormuş. Bu dizinden haberim zaten vardı lakin java dosyalarının o konuma atılması gerektiğini bilmiyordum :). O dizinde myclasses/com/xxx dizini oluşturup, Code.java dosyasını da javac Code.java komutuyla class dosyası oluşturup bu dizine attım ve çalıştı :).
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-08-16, 20:45:30 (UTC -07:00)