From: Yousef on
Hi guys,

I need some help! I actually build a direct connection from JAVA to MATLAB using JMI! Now I just want to use JNI for the connection. There are actually some instructions for doing that.
But it will not work ! I'm using Win7 and MATLAB 7.10.0(R2010a).

I compiled the following code in C to a dll.
-----------------------------------------------------------------------------------------------------------------
#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))) {
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) {
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;
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;
}
-----------------------------------------------------------------------------------------------------------------
Then I used this dll in this java project:

-----------------------------------------------------------------------------------------------------------------
Main Method:
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
//engine.evalString("a =1+2;");
// Retrieve output:
System.out.println(engine.getOutputString(500));
// Close the Matlab session:
engine.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
-----------------------------------------------------------------------------------------------------------------
and the engine:
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&#65533;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(a)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.");
}

}

-----------------------------------------------------------------------------------------------------------------

I receive the Message:


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

Before receiving this message MATLAB starts shortly, but unfortunatly I do not receive a output!

I would be thankful for any help!