# jni funktioniert nicht. jni.h not found



## notizblock (11. Mrz 2006)

hallo

habe begonnen mich mit JNI zu beschäftigen.
gcc: 3.4.5 (ubuntu breezy)
java 1.5

folgende Schritte habe ich durchgeführt:

in das aktuelle Verzeichnis wird kopiert "jni.h" (aus dem JDK)

die JAVA Sourcedatei "test.java" erstellt:

```
public class test {
   public native void drucke(double wert);

   public static void main (String[] args) {
      new test().drucke(25.8);
   }

   static {
      System.loadLibrary("c_drucke");
   }
}
```

die Datei wird übersetzt: javac test.java

dann wird eine Includedatei "test.h" für das C-Programm erzeugt: javah -jni test

danach habe ich das c Source File geschrieben: c_drucke.c

```
#include "test.h"
#include <stdio.h>
#inclede <jni.h>

JNIEXPORT void JNICALL Java_test_drucke
  (JNIEnv *env, jobject obj, jdouble wert)
{
   printf ("Ergebnis:  %10.3lf\n",wert);
}
```

Library path exportiert:

```
LD_LIBRARY_PATH=.
export LD_LIBRARY_PATH
```

aus dieser Datei wird die shared Library erzeugt mit

```
gcc -shared c_drucke.c -o libc_drucke.so
```

beim erzeugen des so-files bekomme ich folgenden Output:


```
flo@malcolm:~/jni$ gcc -shared c_drucke.c -o libc_drucke.so
In Datei, eingefügt von c_drucke.c:1:
test.h:2:17: jni.h: Datei oder Verzeichnis nicht gefunden
In file included from c_drucke.c:1:
test.h:15: Fehler: Syntaxfehler vor "void"
test.h:16: Fehler: Fehler beim Parsen vor »*«-Zeichen
test.h:16: Warnung: Datendefinition hat keinen Typ oder Speicherklasse
c_drucke.c:5: Fehler: Syntaxfehler vor "void"
c_drucke.c:5: Fehler: Fehler beim Parsen vor »*«-Zeichen
c_drucke.c: In function `Java_test_drucke':
c_drucke.c:6: Fehler: »wert« nicht deklariert (erste Benutzung in dieser Funktion)
c_drucke.c:6: Fehler: (Jeder nicht deklarierte Bezeichner wird nur einmal aufgeführt
c_drucke.c:6: Fehler: für jede Funktion in der er auftritt.)
```

Ist das Problem bekannt?
Leider kenne ich mich in C fast überhaupt ned aus, deswegen weiß ich auch ned recht, wie ich mir da helfen soll.
Könnt ihr mir da weiterhelfen?

mit besten grüßen 
flo


----------



## Murray (11. Mrz 2006)

#include mit Anführungszeichen findet die Datei im aktuellen Verzeichnis (klappt mit test.h ja auch), die Schreibweise mit den spitzen Klammern findet Standard-Libraries (klappt ja auch mit stdio.h). Daher reicht es nicht, jni.h ins aktuelle Verzeichnis zu kopieren. Du könntest jetzt zwar #include "jni.h" schreiben, aber da von jni.h wiederum andere Header-Files nachgeladen werden, kommt dann der Fehler etwas später.

Abhilfe: du machst das Verzeichnis, in dem jni.h liegt (und die anderen Header-File auch), als Standard-Header-Verzeichnis bekannt.

Beim gcc geht das m.W. mit der Option -I,  also etwa

```
gcc -I/path/to/jdk/include -shared c_drucke.c -o libc_drucke.so
```

Wenn noch weitere Libraries fehlen, kannst Du beim -I auch mehrere Verzeichnisse mit ; getrennt angeben


----------



## notizblock (11. Mrz 2006)

danke jetzt lässt sich auch das C-Programm kompilieren. Nun gibts aber schon wieder ein neues Problem:

beim start des Programms: java test

ergibt sich folgendes Problem:

```
Exception in thread "main" java.lang.UnsatisfiedLinkError: no libc_drucke.so in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
        at java.lang.Runtime.loadLibrary0(Runtime.java:822)
        at java.lang.System.loadLibrary(System.java:992)
        at test.<clinit>(test.java:10)
```

Wie kann ich den java library Path konfigurieren?
Oder liegt das Problem wieder wo anders?

mit besten Grüßen


----------



## Murray (11. Mrz 2006)

```
java -Djava.library.path=/some/path/  ...
```


----------



## notizblock (11. Mrz 2006)

herzlichen Dank für deine Hilfe!

problem gelöst


----------



## SammY (31. Mrz 2006)

Tut mir leid das ich nochmal nachfrage aber welchen pfad muss ich da angeben??

Danke schon mal im vorraus für eure Hilfe.

Gruß Sammy


----------



## thE_29 (31. Mrz 2006)

Denn du willst 

Oder du legst es einfach in die Standard Library Pfade!

Glaube das aktuelle Verzeichnis zählt da auch dazu!


Und nochwas zu dem jni.h Problem!

Er hat es ja via <jni.h> eingefügt (daher hat es net im aktuellen Verzeichnis nachgesehen)

Aber am besten einfach alles in die anderen include dirs kopieren!


----------



## SammY (31. Mrz 2006)

Habs jetzt geschaft das die UnsatisfiedLinkError - Exception nicht mehr kommt.
Hab aber jetzt ein weiteres Problem.

Und zwar wenn ich das Programm mit: *java test* ausführe bekomme ich keine Ausgabe. Gar nichts.

Ich poste jetzt einfach mal meine Dateien.

*test.java*

```
public class test{

	public native void out(int i);
	
	public static void main(String[] args){
		System.out.println("Hallo Welt!!");
		new test().out(10);
	}
	
	static{
		System.loadLibrary("c_out");
	}
}
```

*c_out.c*

```
#include "test.h"
#include <stdio.h>
#include <jni.h>

JNIEXPORT void JNICALL Java_test_out(JNIEnv *env, jobject obj, jint wert){
	printf("Ergebnis:  %10\n", wert);
}
```

Die selbst generierte Headerdatei *test.h*

```
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class test */

#ifndef _Included_test
#define _Included_test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     test
 * Method:    out
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_test_out
  (JNIEnv *, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif
```

dann hab ich mit dem Befehl: * gcc -c c_out.c *
die c_out.o Datei erstellt und dann die dll-Datei generieren lassen:

*gcc -shared -o c_out.dll c_out.o*
[/b]


----------



## Murray (31. Mrz 2006)

Sammy hat gesagt.:
			
		

> Tut mir leid das ich nochmal nachfrage aber welchen pfad muss ich da angeben??


Da gehört das Verzeichnis hin, in dem die Native-Library (z.B. unter Windows als DLL) steht. Wenn eine Anwendung mehrere Libraries braucht, die in verschiedenen Verzeichnissen stehen, dann kann man auch mehrere Verzeichnise mit ";" getrennt angeben.



			
				thE_29 hat gesagt.:
			
		

> Und nochwas zu dem jni.h Problem!
> 
> Er hat es ja via <jni.h> eingefügt (daher hat es net im aktuellen Verzeichnis nachgesehen)
> 
> Aber am besten einfach alles in die anderen include dirs kopieren!



Die Includes aus dem JDK sollte man auf jeden Fall da lassen, wo sie sind, da jni.h wiederum andere Header-Files mit include <...> und (eben nicht per include "...") einbinden will - da müsste man noch die kopierten Header-Files ändern, was spätestens beim Umstieg auf ein neues JDK die nächsten Probleme macht.

Eigene Header würde ich lieber nicht in die Include-Dirs des JDKs kopieren - zumindest dann nicht, wenn man a) mit dem JDK verschiedene Projekte realisieren will und b) sein Projekt u.U. auch mit einem anderen JDK übersetzen will.


----------



## Murray (31. Mrz 2006)

Probier mal:

```
public class test{

   public native void out(int i);
   
   public static void main(String[] args){
      System.out.println("Hallo Welt!!"); System.out.flush();
      new test().out(10);
      System.out.println( "Done"); System.out.flush();
   }
   
   static{
      System.out.println( "loading library..."); System.out.flush();
      try {
            System.loadLibrary("c_out");
            System.out.println( "OK"); System.out.flush();
     } catch ( Exception ex) {
            ex.printStackTrace();
     } catch ( Error er) {
            er.printStackTrace();
     }
   }
}
```

Zumindest die Ausgaben aus der Java-Welt sollten doch zu sehen sein.

OT: Klassennamen sollte man lieber groß schreiben.


----------



## SammY (31. Mrz 2006)

Hab ich mal gemacht:

```
public class test{

	public native void out(int i);
	
	public static void main(String[] args){
		System.out.println("Hallo Welt!!");
		new test().out(10);
	}
	
	static{
		System.out.println( "loading library..."); 
		System.out.flush(); 
                                try { 
                                   System.loadLibrary("c_out"); 
                                   System.out.println( "OK"); System.out.flush(); 
                                } catch ( Exception ex) { 
    			 System.out.println("Fehler1: " + ex.toString());
                                } catch ( Error er) { 
                                                   System.out.println("Fehler2: " + er.toString());
                                } 
	}
}
```

Die einzige Ausgabe:

loading library...

*Weder ein OK noch eine Fehlermeldung.*
Hab ich vielleicht die dll falsch benannt??

*libc_out.dll*


----------



## Murray (31. Mrz 2006)

Wenn die Lib so eingebunden wird

```
System.loadLibrary("c_out")
```
, dann muss es - unter Windows - im Library-Path eine Datei namens
*c_out.dll*
geben, also ohne das "lib" am Anfang.


----------



## Murray (31. Mrz 2006)

Und versuch doch noch
  java *-verbose* test
,damit sieht man hoffentlich mehr.


----------



## SammY (31. Mrz 2006)

Mehr sehen tu ich schon aber irgendwie nichts was mir weiterhelfen könnte.

Es kommen nur die ganzen OPENED und LOADED sachen.


----------



## Murray (31. Mrz 2006)

Du kannst die Ausgaben auch noch etwas einschränken:
java -verbose:jni test

Poste doch mal die Ausgabe.


----------



## SammY (31. Mrz 2006)

```
$ java -verbose:jni test
[Dynamic-linking native method java.lang.StrictMath.pow ... JNI]
[Dynamic-linking native method java.lang.Float.intBitsToFloat ... JNI]
[Dynamic-linking native method java.lang.Double.longBitsToDouble ... JNI]
[Dynamic-linking native method java.lang.Float.floatToIntBits ... JNI]
[Dynamic-linking native method java.lang.Double.doubleToLongBits ... JNI]
[Dynamic-linking native method java.lang.Object.registerNatives ... JNI]
[Registering JNI native method java.lang.Object.hashCode]
[Registering JNI native method java.lang.Object.wait]
[Registering JNI native method java.lang.Object.notify]
[Registering JNI native method java.lang.Object.notifyAll]
[Registering JNI native method java.lang.Object.clone]
[Dynamic-linking native method java.lang.System.registerNatives ... JNI]
[Registering JNI native method java.lang.System.currentTimeMillis]
[Registering JNI native method java.lang.System.nanoTime]
[Registering JNI native method java.lang.System.arraycopy]
[Dynamic-linking native method java.lang.Thread.registerNatives ... JNI]
[Registering JNI native method java.lang.Thread.start0]
[Registering JNI native method java.lang.Thread.stop0]
[Registering JNI native method java.lang.Thread.isAlive]
[Registering JNI native method java.lang.Thread.suspend0]
[Registering JNI native method java.lang.Thread.resume0]
[Registering JNI native method java.lang.Thread.setPriority0]
[Registering JNI native method java.lang.Thread.yield]
[Registering JNI native method java.lang.Thread.sleep]
[Registering JNI native method java.lang.Thread.currentThread]
[Registering JNI native method java.lang.Thread.countStackFrames]
[Registering JNI native method java.lang.Thread.interrupt0]
[Registering JNI native method java.lang.Thread.isInterrupted]
[Registering JNI native method java.lang.Thread.holdsLock]
[Registering JNI native method java.lang.Thread.getThreads]
[Registering JNI native method java.lang.Thread.dumpThreads]
[Dynamic-linking native method java.lang.Class.registerNatives ... JNI]
[Registering JNI native method java.lang.Class.getName0]
[Registering JNI native method java.lang.Class.getSuperclass]
[Registering JNI native method java.lang.Class.getInterfaces]
[Registering JNI native method java.lang.Class.getClassLoader0]
[Registering JNI native method java.lang.Class.isInterface]
[Registering JNI native method java.lang.Class.getSigners]
[Registering JNI native method java.lang.Class.setSigners]
[Registering JNI native method java.lang.Class.isArray]
[Registering JNI native method java.lang.Class.isPrimitive]
[Registering JNI native method java.lang.Class.getComponentType]
[Registering JNI native method java.lang.Class.getModifiers]
[Registering JNI native method java.lang.Class.getDeclaredFields0]
[Registering JNI native method java.lang.Class.getDeclaredMethods0]
[Registering JNI native method java.lang.Class.getDeclaredConstructors0]
[Registering JNI native method java.lang.Class.getProtectionDomain0]
[Registering JNI native method java.lang.Class.setProtectionDomain0]
[Registering JNI native method java.lang.Class.getDeclaredClasses0]
[Registering JNI native method java.lang.Class.getDeclaringClass]
[Registering JNI native method java.lang.Class.getGenericSignature]
[Registering JNI native method java.lang.Class.getRawAnnotations]
[Registering JNI native method java.lang.Class.getConstantPool]
[Registering JNI native method java.lang.Class.desiredAssertionStatus0]
[Registering JNI native method java.lang.Class.getEnclosingMethod0]
[Dynamic-linking native method java.lang.ClassLoader.registerNatives ... JNI]
[Registering JNI native method java.lang.ClassLoader.retrieveDirectives]
[Dynamic-linking native method java.security.AccessController.doPrivileged ... J
NI]
[Dynamic-linking native method java.io.ObjectStreamClass.initNative ... JNI]
[Dynamic-linking native method java.lang.Class.getPrimitiveClass ... JNI]
[Dynamic-linking native method java.security.AccessController.getStackAccessCont
rolContext ... JNI]
[Dynamic-linking native method java.security.AccessController.getInheritedAccess
ControlContext ... JNI]
[Dynamic-linking native method java.lang.System.initProperties ... JNI]
[Dynamic-linking native method java.io.FileInputStream.initIDs ... JNI]
[Dynamic-linking native method java.io.FileDescriptor.initIDs ... JNI]
[Dynamic-linking native method java.io.FileDescriptor.set ... JNI]
[Dynamic-linking native method java.io.FileOutputStream.initIDs ... JNI]
[Dynamic-linking native method sun.misc.Unsafe.registerNatives ... JNI]
[Registering JNI native method sun.misc.Unsafe.getObject]
[Registering JNI native method sun.misc.Unsafe.putObject]
[Registering JNI native method sun.misc.Unsafe.getObjectVolatile]
[Registering JNI native method sun.misc.Unsafe.putObjectVolatile]
[Registering JNI native method sun.misc.Unsafe.getBoolean]
[Registering JNI native method sun.misc.Unsafe.putBoolean]
[Registering JNI native method sun.misc.Unsafe.getBooleanVolatile]
[Registering JNI native method sun.misc.Unsafe.putBooleanVolatile]
[Registering JNI native method sun.misc.Unsafe.getByte]
[Registering JNI native method sun.misc.Unsafe.putByte]
[Registering JNI native method sun.misc.Unsafe.getByteVolatile]
[Registering JNI native method sun.misc.Unsafe.putByteVolatile]
[Registering JNI native method sun.misc.Unsafe.getShort]
[Registering JNI native method sun.misc.Unsafe.putShort]
[Registering JNI native method sun.misc.Unsafe.getShortVolatile]
[Registering JNI native method sun.misc.Unsafe.putShortVolatile]
[Registering JNI native method sun.misc.Unsafe.getChar]
[Registering JNI native method sun.misc.Unsafe.putChar]
[Registering JNI native method sun.misc.Unsafe.getCharVolatile]
[Registering JNI native method sun.misc.Unsafe.putCharVolatile]
[Registering JNI native method sun.misc.Unsafe.getInt]
[Registering JNI native method sun.misc.Unsafe.putInt]
[Registering JNI native method sun.misc.Unsafe.getIntVolatile]
[Registering JNI native method sun.misc.Unsafe.putIntVolatile]
[Registering JNI native method sun.misc.Unsafe.getLong]
[Registering JNI native method sun.misc.Unsafe.putLong]
[Registering JNI native method sun.misc.Unsafe.getLongVolatile]
[Registering JNI native method sun.misc.Unsafe.putLongVolatile]
[Registering JNI native method sun.misc.Unsafe.getFloat]
[Registering JNI native method sun.misc.Unsafe.putFloat]
[Registering JNI native method sun.misc.Unsafe.getFloatVolatile]
[Registering JNI native method sun.misc.Unsafe.putFloatVolatile]
[Registering JNI native method sun.misc.Unsafe.getDouble]
[Registering JNI native method sun.misc.Unsafe.putDouble]
[Registering JNI native method sun.misc.Unsafe.getDoubleVolatile]
[Registering JNI native method sun.misc.Unsafe.putDoubleVolatile]
[Registering JNI native method sun.misc.Unsafe.getByte]
[Registering JNI native method sun.misc.Unsafe.putByte]
[Registering JNI native method sun.misc.Unsafe.getShort]
[Registering JNI native method sun.misc.Unsafe.putShort]
[Registering JNI native method sun.misc.Unsafe.getChar]
[Registering JNI native method sun.misc.Unsafe.putChar]
[Registering JNI native method sun.misc.Unsafe.getInt]
[Registering JNI native method sun.misc.Unsafe.putInt]
[Registering JNI native method sun.misc.Unsafe.getLong]
[Registering JNI native method sun.misc.Unsafe.putLong]
[Registering JNI native method sun.misc.Unsafe.getFloat]
[Registering JNI native method sun.misc.Unsafe.putFloat]
[Registering JNI native method sun.misc.Unsafe.getDouble]
[Registering JNI native method sun.misc.Unsafe.putDouble]
[Registering JNI native method sun.misc.Unsafe.getAddress]
[Registering JNI native method sun.misc.Unsafe.putAddress]
[Registering JNI native method sun.misc.Unsafe.allocateMemory]
[Registering JNI native method sun.misc.Unsafe.reallocateMemory]
[Registering JNI native method sun.misc.Unsafe.setMemory]
[Registering JNI native method sun.misc.Unsafe.copyMemory]
[Registering JNI native method sun.misc.Unsafe.freeMemory]
[Registering JNI native method sun.misc.Unsafe.objectFieldOffset]
[Registering JNI native method sun.misc.Unsafe.staticFieldOffset]
[Registering JNI native method sun.misc.Unsafe.staticFieldBase]
[Registering JNI native method sun.misc.Unsafe.ensureClassInitialized]
[Registering JNI native method sun.misc.Unsafe.arrayBaseOffset]
[Registering JNI native method sun.misc.Unsafe.arrayIndexScale]
[Registering JNI native method sun.misc.Unsafe.addressSize]
[Registering JNI native method sun.misc.Unsafe.pageSize]
[Registering JNI native method sun.misc.Unsafe.defineClass]
[Registering JNI native method sun.misc.Unsafe.defineClass]
[Registering JNI native method sun.misc.Unsafe.allocateInstance]
[Registering JNI native method sun.misc.Unsafe.monitorEnter]
[Registering JNI native method sun.misc.Unsafe.monitorExit]
[Registering JNI native method sun.misc.Unsafe.throwException]
[Registering JNI native method sun.misc.Unsafe.compareAndSwapObject]
[Registering JNI native method sun.misc.Unsafe.compareAndSwapInt]
[Registering JNI native method sun.misc.Unsafe.compareAndSwapLong]
[Registering JNI native method sun.misc.Unsafe.park]
[Registering JNI native method sun.misc.Unsafe.unpark]
[Dynamic-linking native method java.lang.String.intern ... JNI]
[Dynamic-linking native method sun.reflect.Reflection.getCallerClass ... JNI]
[Dynamic-linking native method java.util.concurrent.atomic.AtomicLong.VMSupports
CS8 ... JNI]
[Dynamic-linking native method java.lang.System.setIn0 ... JNI]
[Dynamic-linking native method java.lang.Object.getClass ... JNI]
[Dynamic-linking native method java.lang.Class.forName0 ... JNI]
[Dynamic-linking native method sun.reflect.Reflection.getClassAccessFlags ... JN
I]
[Dynamic-linking native method sun.reflect.NativeConstructorAccessorImpl.newInst
ance0 ... JNI]
[Dynamic-linking native method sun.misc.VM.initialize ... JNI]
[Dynamic-linking native method java.lang.Runtime.maxMemory ... JNI]
[Dynamic-linking native method java.lang.System.setOut0 ... JNI]
[Dynamic-linking native method java.lang.System.setErr0 ... JNI]
[Dynamic-linking native method java.io.FileSystem.getFileSystem ... JNI]
[Dynamic-linking native method java.io.Win32FileSystem.initIDs ... JNI]
[Dynamic-linking native method java.io.WinNTFileSystem.initIDs ... JNI]
[Dynamic-linking native method java.lang.System.mapLibraryName ... JNI]
[Dynamic-linking native method java.io.WinNTFileSystem.getBooleanAttributes ...
JNI]
[Dynamic-linking native method java.io.WinNTFileSystem.canonicalize0 ... JNI]
[Dynamic-linking native method java.lang.ClassLoader$NativeLibrary.load ... JNI]

[Dynamic-linking native method sun.misc.Signal.findSignal ... JNI]
[Dynamic-linking native method sun.misc.Signal.handle0 ... JNI]
[Dynamic-linking native method java.lang.Compiler.registerNatives ... JNI]
[Registering JNI native method java.lang.Compiler.compileClass]
[Registering JNI native method java.lang.Compiler.compileClasses]
[Registering JNI native method java.lang.Compiler.command]
[Registering JNI native method java.lang.Compiler.enable]
[Registering JNI native method java.lang.Compiler.disable]
[Dynamic-linking native method java.lang.ClassLoader$NativeLibrary.find ... JNI]

[Dynamic-linking native method java.security.AccessController.doPrivileged ... J
NI]
[Dynamic-linking native method java.io.WinNTFileSystem.list ... JNI]
[Dynamic-linking native method java.io.WinNTFileSystem.canonicalizeWithPrefix0 .
.. JNI]
[Dynamic-linking native method java.lang.ClassLoader.findLoadedClass0 ... JNI]
[Dynamic-linking native method java.lang.ClassLoader.findBootstrapClass ... JNI]

[Dynamic-linking native method java.lang.Throwable.fillInStackTrace ... JNI]
[Dynamic-linking native method java.security.AccessController.doPrivileged ... J
NI]
[Dynamic-linking native method java.util.zip.ZipFile.initIDs ... JNI]
[Dynamic-linking native method java.io.WinNTFileSystem.getLastModifiedTime ... J
NI]
[Dynamic-linking native method java.util.zip.ZipFile.open ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.getTotal ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.getMappedAddr ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.getMappedLen ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.getEntry ... JNI]
[Dynamic-linking native method java.util.zip.ZipEntry.initIDs ... JNI]
[Dynamic-linking native method java.util.zip.ZipEntry.initFields ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.freeEntry ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.getCSize ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.getSize ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.getMethod ... JNI]
[Dynamic-linking native method java.util.zip.Inflater.initIDs ... JNI]
[Dynamic-linking native method java.util.zip.Inflater.init ... JNI]
[Dynamic-linking native method java.util.zip.Inflater.inflateBytes ... JNI]
[Dynamic-linking native method java.util.zip.ZipFile.read ... JNI]
[Dynamic-linking native method java.io.FileInputStream.open ... JNI]
[Dynamic-linking native method java.io.WinNTFileSystem.getLength ... JNI]
[Dynamic-linking native method java.io.FileInputStream.readBytes ... JNI]
[Dynamic-linking native method java.io.FileInputStream.close0 ... JNI]
[Dynamic-linking native method java.lang.ClassLoader.defineClass1 ... JNI]
[Dynamic-linking native method java.io.FileOutputStream.writeBytes ... JNI]
loading library...
```


----------



## Murray (31. Mrz 2006)

Ich habe das mal nachvollzogen, allerdings mit dem M$-Compiler:

```
cl /I c:\Programme\Java\jdk1.5.0_05\include /I c:\Programme\Java\jdk1.5.0_05\include\win32  /LD /Fec_out.dll *.c
```

Damit bekomme ich folgende Ausgabe:

```
loading library...
OK
Hallo Welt!!
Ergebnis:
Done
```

Wie man sieht, fehlt der Parameter bei der C-Ausgabe. M.E. ist da im C-Programm auch ein Fehler (auch wenn es ein paar Jahre her ist, dass ich mich das letzte mal mit printf auseinandergesetzt habe.

Wenn ich das C-Programm so ändere:

```
#include "test.h"
#include <stdio.h>
#include <jni.h>

JNIEXPORT void JNICALL Java_test_out(JNIEnv *env, jobject obj, jint wert){
   printf("Ergebnis:  %d\n", wert);
}
```

dann erhalte ich folgende Ausgabe:


```
loading library...
OK
Hallo Welt!!
Ergebnis:  10
Done
```


----------



## SammY (31. Mrz 2006)

Wenn ich meine Library so lade:

*System.loadLibrary("hallo");*

Wie muss dann die zugehörige DLL dazu aussehen??


----------



## Murray (31. Mrz 2006)

hallo.dll


----------



## SammY (31. Mrz 2006)

Was bedeutet das in deinem Aufruf??

/LD /Fec_out.dll *.c


----------



## Murray (31. Mrz 2006)

/LD bedeutet DLL erstellen (sonst versucht er, eine Exe zu erzuegen)
/Fe<file> ist der Name der Ausgabedatei (die würde sonst test.dll heissen)
*.c heisst alle C-Dateien (ich hätte auch test.c schreiben können, aber ich bin faul)


----------



## SammY (31. Mrz 2006)

Erzeugt der bei dir dann die dll:

Fec_out.dll ????


----------



## Murray (31. Mrz 2006)

Nein /Fe ist die Compiler-Option; die DLL heisst dann c_out.dll (und kann dann mit System.loadLibrary( "c_out") geladen werden).


----------



## SammY (31. Mrz 2006)

Ich weis echt nicht an was das noch liegen könnte warum ich keine ausgabe bekomme.


----------



## SammY (31. Mrz 2006)

Der Befehl stimmt doch zum erstellen einer dll oder??
gcc -shared -o hallo.dll hallo.o

Die hallo.o Datei hab ich vorher mit
gcc -c hallo.c erstellt.


----------



## thE_29 (31. Mrz 2006)

hehe 

Ich glaub ich weiß warum :bae:

Ich hatte das auch mal!

Mach mal im c code nach dem printf ein

fflush(stdout);


Ich glaube nämlich das er den Buffer einfach net "flushed" und das Programm terminiert, ohne dass das C Programm seine Ausgabe jemals an stdout weitergeleitet hat!

Hatte ich wie gesagt auch mal ^^


----------



## Murray (31. Mrz 2006)

Mit gcc kenne ich mich leider nicht so gut aus, aber so verkehrt sieht das nicht aus. Hast Du den Fehler im C-Programm beseitigt? Soweit ich mich erinnerte, kann bei falschen Formatbeschreibern alles mögliche passieren.


----------



## SammY (31. Mrz 2006)

Ja den hab ich ausgebessert. Ist aber nichts passiert.
Alles noch beim alten.


----------



## thE_29 (31. Mrz 2006)

Ähm, sein printf war eh okay ^^

jdouble steht für double (und da stimmt %lf), wobei hingenen ein jint für long steht und dann ist das printf (von dir) schon mal falsch!

Da ein long mit %ld und nicht mit %d (ist für int) ausgegeben wird.



Bitte probiere das mit dem fflush!!!!



Egal ob ein printf nun falsche Format tags hat oder richtige, eine Ausgabe muss stattfinden, nur sieht das Ausgabeergebnis eben dementsprechend aus!


----------



## SammY (31. Mrz 2006)

Hat von euch einer mal ein Beispielprog.
Ich bekomm es nämlich nicht zum laufen.


----------



## thE_29 (31. Mrz 2006)

Bekommst du es nicht zum Laufen (falls ja, poste Fehler)

oder hast du keine Ausgabe??


----------



## SammY (31. Mrz 2006)

Ich poste jetzt nochmal meine Dateien
Vielleicht findet ihr ja noch einen Fehler.

*Output.java*

```
public class Output{
	static{
		System.out.println("loading Library...");
		System.loadLibrary("out");
		System.out.println("OK");
	}
	
	public static native void printOut(int i);
	
	public static void main(String[] args){
		new Output().printOut(1);
	}
}
```

*out.c*

```
#include <jni.h>
#include "Output.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_Output_printOut(JNIEnv *env, jobject obj, jint wert){
	printf("Hallo Welt!!");
}
```


----------



## Murray (31. Mrz 2006)

thE_29 hat gesagt.:
			
		

> Ähm, sein printf war eh okay ^^
> 
> jdouble steht für double (und da stimmt %lf), wobei hingenen ein jint für long steht und dann ist das printf (von dir) schon mal falsch!
> 
> Da ein long mit %ld und nicht mit %d (ist für int) ausgegeben wird.


Dieser Thread wird nicht einfacher :wink: 

Ich habe hier in letzter Zeit SammY geantwortet, und in dessen Code bekommt die Java-Methode einen int. Native ist das dann natürlich ein jint, und das sollte man mit %d ausgeben, während Sammy einen m.E. ungültigen Formatbeschreiber %10 verwendet hat.



> Egal ob ein printf nun falsche Format tags hat oder richtige, eine Ausgabe muss stattfinden, nur sieht das
> Ausgabeergebnis eben dementsprechend aus!


Stimmt nur bedingt; in C kann tatsächlich bis hin zum Programmabsturz alles passieren, wenn z.B. die Anzahl der Formatbeschreiber und die Anzahl der tatsächlich angegebenen Parameter nicht übereinstimmt.



@Sammy: wieso Beispielprogramm? Dein Programm hat bei mir - mit der Änderung des Formatbeschreibers - funktioniert.


----------



## SammY (31. Mrz 2006)

Versuch bitte mal das Programm Output bei dir zum laufen zu bringen. Danke.


----------



## SammY (31. Mrz 2006)

Nein ich bekomms nicht zum Laufen.
Das problem ist aber das es auch keine Fehler gibt.


----------



## thE_29 (31. Mrz 2006)

ein printf("%10.3f")

heißt gib 10 vor komma stellen und 3 nachkommastellen aus

und wenn nur steht printf("%10f") heißt es halt nur 10 vorkommastellen 

Der Format String hat schon gepasst!

Und solange Sammy NET FÄHIG IST MEINE POSTINGS ZUM LESEN! Verabschiede ich mich hier mit und er soll den Fehler selber rausfinden...


----------



## thE_29 (31. Mrz 2006)

```
#include <jni.h>
#include "Output.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_Output_printOut(JNIEnv *env, jobject obj, jint wert){
   printf("Hallo Welt!!"); 
   fflush(stdout); //mach das mal hier her!!!!! -- wurde von mir schon vor 1 Seite gepostet!!!
}
```


----------



## SammY (31. Mrz 2006)

Wieso ich lese sie doch alle.


----------



## SammY (31. Mrz 2006)

Hab ich ja schon ausprobiert hilft aber leider auch nichts.


----------



## thE_29 (31. Mrz 2006)

So, ich geh das auch mal testn...


kanns ja net sein


----------



## thE_29 (31. Mrz 2006)

Also bei mir gehts einwandfrei!



			
				Ausgabe hat gesagt.:
			
		

> C:\tmp\java>javac Output.java
> 
> C:\tmp\java>cl /I c:\Programme\Java\jdk1.5.0\include /I c:\Programme\Java\jdk1.5.0\include\win32  /LD /Feout.dll out.c
> Microsoft (R) 32-Bit C/C++-Standardcompiler Version 13.00.9466 für 80x86
> ...




Habe output.java mit dem java von dir
und out.c (habe keine output.h) wo der c code (sogar ohne fflush) drinnen steht!


----------



## SammY (31. Mrz 2006)

Vielleicht liegts da drann das ihr den cl compiler hernehmt und ich den gcc ??


----------



## thE_29 (31. Mrz 2006)

ich teste mit gcc auch noch!


Hast du den gcc auf win32 oder linux und wie gehn da die params für dll erstellen?!? (du könntest dir den visual studio.net compiler downloaden, der is glaube ich grats, bzw das ganze visual studio.ne express oder so)


Saug dir mal meine dll: http://members.inode.at/j.taschek/out.dll


----------



## SammY (31. Mrz 2006)

Hab ihn auf win32 am laufen.


----------



## thE_29 (31. Mrz 2006)

Aso, hab nur einen für linux!

Gehts mit meiner dll?


----------



## SammY (31. Mrz 2006)

Ja jetzt gings bis auf eine Fehlermeldung.

loading library........
OK
closing...
Hallo Welt!!
Exception in thread "main" java.lang.UnsatisfiedLinkError: out
        at test.out(Native Method)
        at test.main(test.java:19)


----------



## SammY (31. Mrz 2006)

gcc -shared -o new_out.dll c_out.c

so erstelle ich eine dll.


----------



## thE_29 (31. Mrz 2006)

Naja, was steht bei dir in Zeile 19?

So ich:

gcc out.c -o out.so -shared -I/usr/java/j2sdk1.4.2_03/include -I/usr/java/j2sdk1.4.2_03/include/linux 


Achtung, das ist Linux! Dort heißen die Dinger .so und net .dll


----------



## SammY (31. Mrz 2006)

Also egal was ich mache mein DLL funzt net.
Die deine funzt schon bei mir


----------



## SammY (31. Mrz 2006)

Sorry.

In Zeile 19 steht:

new test().out(10);


----------



## thE_29 (31. Mrz 2006)

http://public.cabit.wpcarey.asu.edu/janjua/java/jni/

Probier das hier mal!

Uha, natürlich musst du den Linux Pfad durch Windows ersetzen und nicht .so sondern .dll!


----------



## SammY (3. Apr 2006)

Also ich wollte mich nur nochmal bei allen die mir geholfen haben bedanken.

Habs mir jetzt den Microsoft Standard Compiler runtergeladen und jetzt funzt alles.

DANKE FÜR EURE HILFE.


----------

