erneutes problem mit JNI

Taramsis

Bekanntes Mitglied
Hi Leute,

in dem Thread http://www.java-forum.org/allgemeine-java-themen/102689-jni-problem.html wollteich im Helloworld-kontext eine dll über JNI in Java aufrufen und habe es mit Hilfe geschaft.
Mei Ziel ist es nun eine Schnittstelle zu Matlab zu bauen und hierfür möchte ich folgende C datei zu einer dll kompilieren:
Code:
#include <jni.h>
#include "MatlabNativeInterface_Engine.h"
#include <stdio.h>
#include "engine.h"

#define DEFAULT_BUFFERSIZE 65536

Engine* ep;

char outputBuffer[DEFAULT_BUFFERSIZE];

JNIEXPORT void JNICALL 
Java_MatlabNativeInterface_Engine_open(JNIEnv *env, jobject obj, const jstring startcmd) {
  
	const char *c_string = (*env)->GetStringUTFChars(env, startcmd, 0);
	if (!(ep = engOpen(c_string))) {
	if (ep == NULL ) {
		jclass exception;
		(*env)->ReleaseStringUTFChars(env, startcmd, c_string);
		exception = (*env)->FindClass(env, "java/io/IOException");
		if (exception == 0) return;
		(*env)->ThrowNew(env, exception, "Opening Matlab failed.");
		return;
	}
	(*env)->ReleaseStringUTFChars(env, startcmd, c_string);
	/* indicate that output should not be discarded but stored in */
	/* outputBuffer */
	engOutputBuffer(ep, outputBuffer, DEFAULT_BUFFERSIZE);
  }

JNIEXPORT void JNICALL 
Java_MatlabNativeInterface_Engine_close(JNIEnv *env, jobject obj) {
	engClose(ep);
	if (engClose(ep) == 1) {
		jclass exception;
		exception = (*env)->FindClass(env, "java/io/IOException");
		if (exception == 0) return;
		(*env)->ThrowNew(env, exception, "Closing Matlab failed.");
		return;
	}
}

JNIEXPORT void JNICALL
Java_MatlabNativeInterface_Engine_evalString(JNIEnv *env, jobject obj, const jstring j_string) {
	const char *c_string;
	engEvalString(ep, c_string);
	c_string = (*env)->GetStringUTFChars(env, j_string, 0);
	if (engEvalString(ep, c_string) != 0) {
		jclass exception;
		exception = (*env)->FindClass(env, "java/io/IOException");
		if (exception == 0) return;
		(*env)->ThrowNew(env, exception, "Error while sending/receiving data.");
	}
	(*env)->ReleaseStringUTFChars(env, j_string, c_string);
}

JNIEXPORT jstring JNICALL
Java_MatlabNativeInterface_Engine_getOutputString(JNIEnv *env, jobject obj, jint numberOfChars) {
	char *c_string;
	jstring j_string;
	if (numberOfChars > DEFAULT_BUFFERSIZE) {
		numberOfChars = DEFAULT_BUFFERSIZE;
	}
	c_string = (char *) malloc ( sizeof(char)*(numberOfChars+1) );
	c_string[numberOfChars] = 0;
	strncpy(c_string, outputBuffer, numberOfChars);
	j_string = (*env)->NewStringUTF(env, c_string);
	free(c_string);
	return j_string;
}

Diese Vorlage habe ich von Mathworks! Die entsprechende Header Datei habe ich aus der Java Datei erstellt:

Java:
package MatlabNativeInterface;

import java.io.*;

/**
 * <b>Java Engine for Matlab via Java Native Interface (JNI)</b><br>
 * This class demonstrates how to call Matlab from a Java program via 
 * JNI, thereby employing Matlab as the computation engine.
 * The Matlab engine operates by running in the background as a separate
 * process from your own program.
 * <p>
 * Date: 04.04.03
 * <p>
 * Copyright (c) 2003 Andreas Klimke, Universit�t Stuttgart
 * <p>
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions: 
 * <p>
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * <p>
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * @author W. Andreas Klimke, University of Stuttgart 
 *         (klimke@ians.uni-stuttgart.de)
 * @version 0.1
 *
 */
public class Engine {
	
	/**
	 * Calls the function <code>engOpen</code> of Matlab's C Engine library. 
	 * Excerpts from the Matlab documentation:
	 * "On UNIX systems, if startcmd is NULL or the empty string, 
	 * <code>engOpen</code> starts MATLAB on the current host using the 
	 * command <code>matlab</code>. If startcmd is a hostname, <code>engOpen
	 * </code> starts MATLAB on the designated host by embedding the specified 
	 * hostname string into the larger string:
   * <code>rsh hostname \"/bin/csh -c 'setenv DISPLAY\ hostname:0; matlab'\"
	 * </code>. If startcmd is any other string (has white space in it, or 
	 * nonalphanumeric characters), the string is executed literally to start 
	 * MATLAB. On Windows, the startcmd string must be NULL."<br>	 
   * See the Matlab documentation, chapter "External Interfaces/API 
	 * Reference/C Engine Functions" for further information. 

	 * @param startcmd The start command string.
	 * @throws IOException Thrown if starting the process was not successful.
	 */
  public native void open(String startcmd) throws IOException;

	/**
	 * Calls the function <code>engClose</code> of Matlab's C Engine
	 * library.	This routine allows you to quit a MATLAB engine session.
	 * @throws IOException Thrown if Matlab could not be closed. 
	 */
	public native void close() throws IOException;

	/**
	 * Calls the function <code>engEvalString</code> of Matlab's C Engine
	 * library. Evaluates the expression contained in string for the MATLAB 
	 * engine session previously started by <code>open</code>.
   * See the Matlab documentation, chapter "External Interfaces/API 
	 * Reference/C Engine Functions" for further information. 
	 * @param str Expression to be evaluated.
	 * @throws IOException Thrown if data could not be sent to Matlab. This
	 *                     may happen if Matlab is no longer running.
	 * @see #open
	 */
  public native void evalString(String str) throws IOException;

	/**
	 *  Reads a maximum of <code>numberOfChars</code> characters from 
	 * the Matlab output buffer and returns the result as String.<br> 
	 * If the number of available characters exceeds <code>numberOfChars</code>,
	 * the additional data is discarded. The Matlab process must be opended
	 * previously with <code>open()</code>.<br>
	 * @return String containing the Matlab output.
	 * @see #open
	 * @throws IOException Thrown if data could not be received. This may
	 *                     happen if Matlab is no longer running.
	 */
  public native String getOutputString(int numberOfChars);

	/**
	 * Initialize the native shared library.
	 */
  static {
    System.loadLibrary("EngineDll_St");
		System.err.println("Native Matlab shared library loaded.");
  }
	
}

Ich hab mal extra die Kommentare drin gelassen! Diese Java Vorlagen wurden soweit ich es entnehmen konnte für Linux erstellt. Ich jedoch benutze Windows. Meine Main Methode sieht wie folgt aus:

Java:
package main;

import MatlabNativeInterface.*;
import java.io.*;

/**
 * Demonstration program for connecting Java with Matlab using the Java
 * Native Interface (JNI). Wrapper functions access Matlab via Matlab's 
 * native C Engine library.
 **/
public class Main {
	public static void main(String[] args) {
		Engine engine = new MatlabNativeInterface.Engine();
		try {
			// Matlab start command:
			engine.open("matlab -nosplash -nojvm");
			// Display output:
			System.out.println(engine.getOutputString(500));
      // Example: Solve the system of linear equations Ax = f with
			// Matlab's Preconditioned Conjugate Gradients method.
			engine.evalString("A = gallery('lehmer',10);");  // Define Matrix A
			engine.evalString("f = ones(10,1);");            // Define vector f
			engine.evalString("pcg(A,f,1e-5)");              // Compute x
                        // Retrieve output:
			System.out.println(engine.getOutputString(500));
			// Close the Matlab session:
			engine.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Nun habe ich über VS2010 die C datei kompiliert, doch bekomme ich unter Java die abgefangene Nachricht beim öffnen von Matlab:

Native Matlab shared library loaded.
java.io.IOException: Opening Matlab failed.
at MatlabNativeInterface.Engine.open(Native Method)
at main.Main.main(Main.java:16)

Da diese Vorlage schon häufig benuzt wurd bin ich der meinung das der Code an sich in Ordnung ist und das bei der kompilierung etwas falsch sein muss.
Da ich bei der kompilierung auch einige DLL includen muss frage ich mich, ob man dies bei MingW auch nun über -I machen kann. Leider klappte die kompilierung über MingW bisher nicht und ich weiß nicht ob ich VS2010 trauen kann!
Würde mich über jede Hilfe freuen!
 
G

Gastredner

Gast
Das System funktioniert doch genauso, wie es funktionieren sollte: Du versuchst die Engine zu öffnen, dies funktioniert jedoch nicht und die native Methode wirft daraufhin eine IOException:
Code:
if (!(ep = engOpen(c_string))) {
	if (ep == NULL ) {
		jclass exception;
		(*env)->ReleaseStringUTFChars(env, startcmd, c_string);
		exception = (*env)->FindClass(env, "java/io/IOException");
		if (exception == 0) return;
		(*env)->ThrowNew(env, exception, "Opening Matlab failed.");
		return;
	}
Ich würde also eher mal deine Eingabe beim Öffnen der Engine überprüfen.
 

Taramsis

Bekanntes Mitglied
Ich würde also eher mal deine Eingabe beim Öffnen der Engine überprüfen.

Das dachte ich auch eigentlich, aber mir fällt nichts ein! laut der engine.java heißt es unter Windows soll "startcmd" null sein. Nun dachte ich ich muss in der C datei soetwas machen:
Vorher:

Code:
NIEXPORT void JNICALL 
Java_MatlabNativeInterface_Engine_open(JNIEnv *env, jobject obj, const jstring startcmd) {
  	const char *c_string = (*env)->GetStringUTFChars(env, startcmd, 0);
	if (!(ep = engOpen(c_string))) {
	        jclass exception;
		(*env)->ReleaseStringUTFChars(env, startcmd, c_string);
		exception = (*env)->FindClass(env, "java/io/IOException");
		if (exception == 0) return;
		(*env)->ThrowNew(env, exception, "Opening Matlab failed.");
		return;
	}
	(*env)->ReleaseStringUTFChars(env, startcmd, c_string);
	/* indicate that output should not be discarded but stored in */
	/* outputBuffer */
	engOutputBuffer(ep, outputBuffer, DEFAULT_BUFFERSIZE);
  }
Entweder alle "startcmd" durch NULL ersetzen außer im Konstriktor. In einem MATLAB Beispeil sah ich folgendes:
Code:
ep = engOpen(NULL);
Aber selbst, wenn ich nur diese Zeile einfüge kommt wird die nächste Exception abgefangen bei evalString.

Ich habe in meiner java main Klasse versucht folgendes zu machen:

Java:
// Matlab start command:
	engine.open(null);

Aber dann erhalte ich einen fatal Error ind der JRE!
Bin langsam verzweifelt!
 
G

Gastredner

Gast
Ich würde an deiner Stelle ja mal dem Hinweis aus dem Javadoc folgen:
Java:
/**
 * See the Matlab documentation, chapter "External Interfaces/API 
 * Reference/C Engine Functions" for further information. 
 */
Da wirst du wohl eher etwas hilfreiches erfahren als hier.

EDIT: Die Doku findest du hier: http://www.mathworks.de/access/helpdesk/help/pdf_doc/matlab/apiext.pdf
Der für dich wohl wichtige Abschnitt startet auf Seite 257, enthält allerdings hauptsächlich nur einen Verweis auf ein Demoprojekt unter matlabroot/extern/examples/eng_mat. Suche dort mal nach einer Antwort/einem funktionierenden Beispiel.
 
Zuletzt bearbeitet von einem Moderator:

Taramsis

Bekanntes Mitglied
Danke! Ich kenne diese Quelle schon! Und das Beispielauch! Mein Hauptproblem ist wie ich denke die adaption in Windows, da die Vorlage für Linux angelegt ist.
Für weitere Vorschläge bin ich dankbar!
 

kay73

Bekanntes Mitglied
Java:
engine.open("matlab -nosplash -nojvm");
sieht doch sehr nach einem stinknormalen Shellcommando aus, das ausgefuehrt wird und ein binary namens "matlab" startet, dass z. B. im $PATH liegt.

Fueg doch unter Windows entweder das Matlab Verzeichnis zum %PATH% hinzu oder rufe
Java:
engine.open("C:\\Programme\\MATLAB\\bin\\matlab.exe -nosplash -nojvm");
oder so auf...
 

Taramsis

Bekanntes Mitglied
Fueg doch unter Windows entweder das Matlab Verzeichnis zum %PATH% hinzu

Hab ich schon gemacht, sonst würde es nicht kurz starten und wieder verschwinden!
Ich denke es muss an der kompilierten DLL liegen. Dependency Walker zeigte mir einige Fehlende DLLs die ich manuel hinzugefügt habe(in den Java Path). Danach waren die fehlenden (laut depends) verschwunden, doch trotzdem zeigt er mir folgende Meldung an:

Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

Und zwei dlls sind rötlich dargestellt! Habe diese auch ersetzt, leder ohne Erfolg.
Ist es normal, dass man nach der Kompilierung noch fehlende DLLs hinzufügen muss?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Problem mit dem Lesen einer projektinternen .csv aus der runnable JAR Allgemeine Java-Themen 3
krgewb Problem mit Umlauten und Eszett bei InputStream Allgemeine Java-Themen 3
Max246Sch Backtracking Problem Box Filler Allgemeine Java-Themen 6
NightVision402 VisualVM Startskript Problem Allgemeine Java-Themen 3
javaBoon86 Email Server Connection Problem Allgemeine Java-Themen 1
F Problem mit PDFBOX Library Allgemeine Java-Themen 1
A Java modul Problem Allgemeine Java-Themen 4
D Read JSON File Problem Allgemeine Java-Themen 9
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
J Problem mit JasperReports Allgemeine Java-Themen 8
M log4j Problem mit jlink Allgemeine Java-Themen 19
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
torresbig Website login Problem - Jsoup, wie bisher, klappt nicht! Allgemeine Java-Themen 31
P Selenium . getText Problem Allgemeine Java-Themen 9
A Jar zu Exe Problem Allgemeine Java-Themen 13
sserio Variablen Liste erstellt und ein Problem mit dem Index Allgemeine Java-Themen 6
S Folgendes Problem bei einem Programm Allgemeine Java-Themen 1
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
A Thread.sleep Problem Allgemeine Java-Themen 2
A Problem bei der Nachbarschafttest Allgemeine Java-Themen 11
Splayfer Problem: no main manifest attribute Allgemeine Java-Themen 3
G javamail Problem beim Empfangen von Nachrichten Allgemeine Java-Themen 3
Splayfer JDA Problem mit MessageCounter Allgemeine Java-Themen 0
Splayfer Problem mit BufferedWriter Allgemeine Java-Themen 3
F Streams als Alternative für dieses Problem ? Allgemeine Java-Themen 15
N Maven Problem mit Datenbanktreiber (H2 Embedded) Allgemeine Java-Themen 12
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
B Einfach Elemente zweier Arraylisten kreuz und quer vergleichen, min und max Problem? Allgemeine Java-Themen 16
C ArrayList Problem Allgemeine Java-Themen 3
kev34 nim-Spiel problem Allgemeine Java-Themen 1
D Firebase retrieve data Problem, Child Element wird nicht angesprochen Allgemeine Java-Themen 0
G Welches Problem besteht bei den Typparametern? Allgemeine Java-Themen 5
temi Problem mit Aufrufreihenfolge bei Vererbung Allgemeine Java-Themen 3
Sumo_ow "ArrayIndexOutofBoundsException: 2" Array Problem Allgemeine Java-Themen 6
T PIM basierend auf netbeans via AnyDesk Problem Allgemeine Java-Themen 3
xGh0st2014 Problem mit Java Array Allgemeine Java-Themen 1
Kirby.exe Verständnis Problem bei Rucksack Problem Allgemeine Java-Themen 6
B Eclipse-Lombok-Problem Allgemeine Java-Themen 19
I Input/Output ObjectOutputStream - Problem Allgemeine Java-Themen 7
1 Multiple Choice Knapsack- Problem Allgemeine Java-Themen 2
kodela Problem mit strukturiertem Array Allgemeine Java-Themen 18
E Problem mit Gridlayout und Button Allgemeine Java-Themen 2
A Array Problem Allgemeine Java-Themen 8
bueseb84 Problem Allgemeine Java-Themen 0
S Problem mit Arrays Allgemeine Java-Themen 1
D Nullpointer Exception Problem Allgemeine Java-Themen 5
B Problem mit meinen Klassen Allgemeine Java-Themen 6
A HashMap Methode "get()"-Problem Allgemeine Java-Themen 28
J Problem beim Umstellen auf Java jdk 13 Allgemeine Java-Themen 3
J Problem bei Install java 13 Allgemeine Java-Themen 3
X Profitable Reise Problem Allgemeine Java-Themen 32
A Problem beim öffnen von Java-Installern Allgemeine Java-Themen 1
Dann07 Problem mit JavaMail API Allgemeine Java-Themen 26
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
L Klassen Algorithmus für das folgende Problem entwickeln? Allgemeine Java-Themen 30
J Clear-Problem Allgemeine Java-Themen 10
B Problem zu einem Java Projekt Allgemeine Java-Themen 6
S JFileChooser Problem Allgemeine Java-Themen 4
M Traveling Salesman - MST Heuristik Problem Allgemeine Java-Themen 4
J Traveling Salesman Problem Allgemeine Java-Themen 14
E Java Editor Problem mit 2er Exceptions Allgemeine Java-Themen 12
C code oder Bibliotheken für 2-Center Problem Allgemeine Java-Themen 4
M Salesman Problem - Bruteforce Algorithmus Allgemeine Java-Themen 23
S Methoden Problem mit NullPointerException Allgemeine Java-Themen 9
Javafan02 Problem mit if-clause Allgemeine Java-Themen 17
J Lombok Problem mit Konstruktoren bei Verberbung Allgemeine Java-Themen 1
kodela Event Handling Problem mit der Alt-Taste Allgemeine Java-Themen 16
W Threads Problem Allgemeine Java-Themen 15
D (Verständnis-)Problem mit Unterklasse Allgemeine Java-Themen 4
S Problem mit Generic bei unmodifiableCollection Allgemeine Java-Themen 4
S jserialcomm Problem Allgemeine Java-Themen 1
Flynn Thread-Problem... Allgemeine Java-Themen 2
J Generische Interface - Problem Allgemeine Java-Themen 3
G Problem beim GUI Allgemeine Java-Themen 9
L Applet Problem "security: Trusted libraries list file not found" ? Allgemeine Java-Themen 7
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
T Problem mit externen Datenbankzugriff über SSH Tunnel Allgemeine Java-Themen 4
F Problem beim Einlesen einer Textdatei Allgemeine Java-Themen 12
S Java OpenOffice Problem mit Windows-Benutzerwechsel Allgemeine Java-Themen 19
K Threads RAM Problem Allgemeine Java-Themen 20
P Operatoren Problem mit Zähler in recursiver Schleife Allgemeine Java-Themen 2
C Int Problem Allgemeine Java-Themen 8
C J2V8 NodeJs Java Bride Problem und Frage!?!? Allgemeine Java-Themen 1
J Problem bei Hashmap Key-Abfrage Allgemeine Java-Themen 4
C Webseiten Programm problem Allgemeine Java-Themen 5
M LocalDate Problem Allgemeine Java-Themen 4
J "Problem Objektorientierung" Allgemeine Java-Themen 20
geekex Problem Meldung! Was tun?! Allgemeine Java-Themen 19
T Klassen Override Problem Allgemeine Java-Themen 7
L Unbekanntes Problem Allgemeine Java-Themen 1
FrittenFritze Problem mit einer JComboBox, Event temporär deaktivieren Allgemeine Java-Themen 11
Blender3D Java Swing Programm Windows 10 Autostart Problem Allgemeine Java-Themen 2
F HTTPS Zertifikat Problem Allgemeine Java-Themen 3
M OpenCV KNearest Problem Allgemeine Java-Themen 0
Tommy Nightmare Project Euler: Problem 22 Allgemeine Java-Themen 2
C Abstrakte Klasse, lokale Variable-Problem Allgemeine Java-Themen 1
N Vererbung Design-Problem mit vorhandenen, von der Klasse unabhängigen Methoden Allgemeine Java-Themen 12
P Eclipse Projekt anlegen macht Problem Allgemeine Java-Themen 1
RalleYTN META-INF/services Problem Allgemeine Java-Themen 3
F Java Mail Problem: Authentifizierung wird nicht immer mitgeschickt Allgemeine Java-Themen 1

Ähnliche Java Themen

Neue Themen


Oben