Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » komplilierungs probleme

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
15.07.2010, 10:54 Uhr
Mondragon



Hi Leute,

ich bin ein noob im Thema C++ und möchte es eigentlich für java zwecke misbrauchen!

Ich versuche eine Anbindung von Java an MATLAB über C zu bauen und nutze hierbei JNI. Mein Problem ist nun (nehme ich jetzt an!) das bei der Kompilierung (mit VS2010) der folgenden C datei zu einer dll etwas schief läuft und deshalb Java, MATLAB zwar kurz öffnet, mir aber die entsprechende Exception ausgibt:

Zitat:

Opening Matlab failed.




C++:
#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);
    ep = engOpen(NULL);
  //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;
}



Ich nehme an das die kompilierte dll fehlerhaft sein muss, da Dependency Walker mir fehlende DLLs anzeigt. Dieses problem konnte ich beheben indem ich die DLLs einfach aus dem Netz heruntergeladen habe. Ich habe auch alle von Matlab und java geforderten pfade hinzugefügt.
Leider klappte eine Kompilierung über z.B. MingW überhaupt nicht:
g++ -IC:/XXX/jdk/include -IC:/XXX/jdk/include/win32 -Wl,--add-stdcall-alias -shared -o engine.dll engine.c

Ich würde mich über jede Anregung freuen!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
15.07.2010, 22:03 Uhr
0xdeadbeef
Gott
(Operator)


Ich sehe ein paar offensichtliche Probleme, etwa

C++:
    engClose(ep);
    if (engClose(ep) == 1) {


und

C++:
    const char *c_string;
    engEvalString(ep, c_string);


und generell scheint mir das Konzept, das ganze als state machine aufzuziehen zweifelhaft (wenn open zweimal aufgerufen wird, leckst du Ressourcen), aber ich vermute, dass dieser spezielle Fehler in engOpen steckt; diese scheint NULL zurückzugeben.

Übrigens ist das ganze kein Compilerfehler.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
18.07.2010, 02:01 Uhr
Mondragon




Zitat von 0xdeadbeef:
Ich sehe ein paar offensichtliche Probleme, etwa

C++:
    engClose(ep);
    if (engClose(ep) == 1) {


und

C++:
    const char *c_string;
    engEvalString(ep, c_string);




Was sind den genau die Probleme hier bin leider noch C Anfänger! Eher Java genutzt!


Zitat von 0xdeadbeef:

und generell scheint mir das Konzept, das ganze als state machine aufzuziehen zweifelhaft (wenn open zweimal aufgerufen wird, leckst du Ressourcen), aber ich vermute, dass dieser spezielle Fehler in engOpen steckt; diese scheint NULL zurückzugeben.
Übrigens ist das ganze kein Compilerfehler.

engOpen wird nur einmal Aufgerufen - dass auskommentiert ist das Original!
Ich habe folgende Java Vorlage die mich dazu gebracht hat engOpen NULL zu übergeben:


Code:
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.load("D:/Program Files/MATLAB/R2009b/bin/win32/EngineDll_St.dll");
        System.err.println("Native Matlab shared library loaded.");
  }
    
}




Bei engOpen steht:

Zitat:
On Windows, the startcmd string must be NULL



Und zur Abrundung die Java Main Methode:

Code:
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();
        }
    }
}



Diese Vorlage wurde für Linux gemacht! Ich brauchs für Windows. Würde mich über jede Hilfe freuen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
18.07.2010, 02:52 Uhr
0xdeadbeef
Gott
(Operator)



Zitat von Mondragon:

Was sind den genau die Probleme hier bin leider noch C Anfänger! Eher Java genutzt!


Im ersten Stück wird engClose zweimal aufgerufen, das zweite Mal mit hoher Wahrscheinlichkeit auf einem ungültigen Zeiger. Was das genau macht, kann ich dir nicht sagen, weil ich das C-API, das du da benutzt, nicht kenne, aber es sollte mich nicht wundern, wenn das undefiniertes Verhalten erzeugte.

Im zweiten Stück benutzt du c_string, bevor dieser initialisiert wurde. Das erzeugt mit Sicherheit undefiniertes Verhalten.


Zitat von Mondragon:

engOpen wird nur einmal Aufgerufen - dass auskommentiert ist das Original!


Wenn die open-Methode deiner Java-Klasse zweimal aufgerufen wird, leckst du da Ressourcen, das meinte ich. Auch kannst du so nicht mehr als eine Instanz der Klasse zur selben Zeit benutzen, und das ganze dürfte unangenehm auf Multithreading reagieren.

Mit dem restlichen Zeug kann ich dir nicht wirklich helfen, weil ich (wie oben erwähnt) keine Ahnung habe, was du da benutzt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 18.07.2010 um 02:52 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: