![]() |
| | Themen-Optionen | Thema durchsuchen |
| | Nach oben #1 |
| Neuer Benutzer Registriert seit: 05.08.2008
Beiträge: 3
|
Hallo zusammen, ich versuche gerade ein kleines "HelloWorld"-Programm zu erstellen, welches über JNI von Java aus auf eine C# - Methode zugreift. Dazu habe ich folgende Klassen erstellt: Code:
HelloWorld.java:
public class HelloWorld {
public native void displayHelloWorld();
static {
System.loadLibrary("HelloWorld");
}
}
Main.java:
public class Main {
public static void main (String[] args) {
new HelloWorld().displayHelloWorld();
}
}
Anschließend erstelle ich mit Hilfe der class-files eine Header-Datei: javah -jni HelloWorld HelloWorld.h sieht dann folgendermaßen aus: Code:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Hier die .cpp Datei, welche die native Function beinhaltet: Code:
HelloWorld.cpp:
#include <jni.h>
// This is the java header created using the javah -jni command.
#include "HelloWorld.h"
// This is the Managed C++ header that contains the call to the C#
#include "HelloWorldC.h"
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *jn, jobject jobj) {
HelloWorldC* t = new HelloWorldC();
t->callCSharpHelloWorld();
}
Nun wird das Managed CPP - File für die Verbindung zwischen C++ und C# erstellt: Code:
#using <mscorlib.dll>
#using "CSharpHelloWorld.netmodule"
using namespace System;
public __gc class HelloWorldC
{
public:
CSharpHelloWorld __gc *t; // Provide .NET interop and garbage collecting to the pointer.
HelloWorldC() {
t = new CSharpHelloWorld(); // Assign the reference a new instance of the object
}
// This inline function is called from the C++ Code
void callCSharpHelloWorld() {
t->displayHelloWorld();
}
};
Die C# - Methode auf die zugegriffen werden soll: Code:
using System;
public class CSharpHelloWorld
{
public CSharpHelloWorld() {}
/// <summary>
/// displayHelloWorld will be the method called from within java.
/// </summary>
public void displayHelloWorld()
{
Console.WriteLine("Hello World, from C#!");
}
}
Nun erstellt ich mit csc /target:module /out:CSharpHelloWorld.netmodule <pfad/CSharpHelloWorld.cs> das nötige netmodule welches im ManagedCode gebraucht wird... Zu guter Letzt erzeuge ich aus HelloWorld.cpp eine dll-Datei welche später über java aufgerufen wird und kopiere es in mein Java-Verzeichnis: cl -IF:\java\include -IF:\java\include\win32 -LD F:\HelloWorld.cpp -FeHelloWorld.dll /clr: oldSyntax Funktioniert bis jetzt alles schön und gut, aber nun hab ich folgendes Problem: Wenn ich jetzt Main über CMD oder in Eclipse ausführen will, wird die Fehlermeldung: Can't find dependent libraries... Die dlls die er nicht findet sind: msvcm80.dll und msvcr80.dll Da die dlls auf meiner HD vorhanden waren, kopierte ich die beiden in mein Java-Workspace... Nun findet er diese dlls, jedoch kommt nun beim Ausführen ein Runtime error: R6034 An application has made an attempt to load the C runtime library incorrectly. Please contact the applications support team for more information. Weiss jemand wie man diesen Fehler behebt? Geändert von 19114512 (05.08.2008 um 12:37 Uhr) |
| | |
| | Nach oben #3 |
| Erfahrener Benutzer Registriert seit: 27.02.2006
Beiträge: 159
|
Hallo, steht am Ende. Ganz klar ist es mir nicht, aber ich gehe davon aus, dass Du das ganze mit Java 1.6 gemacht hast. Die jvm.dll nutzt aber msvcrt71.dll und muss per dll die msvcrt80.dll dazu nehmen. Ich gehe hier von einer Überscheidung der zu importierenden Funktionen aus den DLLs aus, so dass hier auch zur Meldung der falschen C runtime version kommt. also das ganze statisch linken in der DLL oder auf universelle crt zurück gehen. Vielleicht kannst Du aber auch per .manifest dem Java eine msvcrt80.dll als Runtime unterschieben. Gruß, Jumper, the II. |
| | |
| | Nach oben #6 |
| Neuer Benutzer Registriert seit: 05.08.2008
Beiträge: 3
|
Zur Verteidigung von Bleistift: Ich hatte mich beim Erstellen des Beitrags verdrückt und diesen zu früh erstellt..deswegen waren am Anfang nur ein paar Zeilen da ja ich arbeite mit java 1.6.... habe nicht so viel Erfahrung mit DLLs, deswegen meine Frage: Wie kann man die DLLs statisch linken? Danke für die Hilfe MfG |
| | |
| | Nach oben #7 |
| Erfahrener Benutzer Registriert seit: 27.02.2006
Beiträge: 159
|
Hallo Nummerchen, gar nicht. Du musst in Deiner Entwicklungsumgebung bekannt machen, dass du die notwendigen Bibliotheken statisch linken willst und keine DLLs einbinden. Das setzt natürlich voraus, dass Du auch die statischen Bibliotheken installiert hast. Wie jetzt konkret die Einstellungen zu machen sind, kann ich mangels Kenntnis und wahrscheinlich auch passender Umegbung nicht sagen. Auch weiß ich nicht, wie sich das .Net Framework dabei verhält. Vielleicht überlegst Du erst einmal, was du erreichen willst. Ggf. überlegen wir hier zusammen. Dann findet sich bestimmt auch eine andere Lösung. Gruß, Jumper, the II. PS: ich bin ein von native Libraries gebranntes Kind, nicht dass sie nicht zu nutzen sein, aber die meisten bauen die native Libraries so, dass sie selten oder gar nicht vernünftig zu nutzen und Systemintegrierbar sind. /EDIT: Umgebung = Entwicklungsumgebung |
| | |
| | Nach oben #8 |
| Neuer Benutzer Registriert seit: 05.08.2008
Beiträge: 3
|
Bevor ich dir erkläre was ich mit JNI machen will, wäre es vl. nicht schlecht zu erwähnen, dass ich wegen meiner Diplomarbeit mit JNI in Kontakt gekommen bin und deswegen einiges noch nicht kenne bzw. mir erarbeiten muss Zu meinem eigentlichen Problem: Ich habe eine Java-Applikation welche bestimmte Daten aus einem CAD - System ausliest (ProEngineer WF2.0) bzw. bearbeitet. Neben der Java - App soll eine C# - GUI erstellt werden, welche es dem User ermöglicht über einfache Auswahlpunkte/Menüs/etc... die Java-Applikation zu steuern, ohne zu wissen was im Hintergrund läuft. Zur Erklärung warum es eine C# - GUI werden soll: Der Großteil der firmentinternen Projekte sind in C# geschrieben, außerdem wird/ist der nötige DB-Zugriff für mein Projekt, zu 60% abgewickelt und ebenfalls in C# codiert.... Die C#-GUI soll nur den DB-Zugriff aufbauen und, wie bereits gesagt JNI soll dazu verwendet werden, verschiedene Befehle zwischen Java und C# zu verschicken (Befehle werden größtenteils Strings sein) bzw. besser gesagt um mit diesen Befehlen bestimmte Methoden aufzurufen. Deswegen wollte ich zunächst das HelloWorld-Programm zum Laufen bringen, um darauf meine Java-C#-Verbindung aufzubauen... aber wie man sieht, macht mir das bisher seeeeeeeeeehr zu schaffen ^^ Kann man das mit JNI realisieren oder gibts es bessere Varianten??? Danke |
| | |
| | Nach oben #9 |
| Projektleiter Registriert seit: 30.11.2005 Ort: Bottrop
Beiträge: 1.133
|
Na ja. Deine JNI-Lösung sieht eine Java, eine C++, eine managed C++ und eine C#-Schicht vor - da muss es bessere wege geben. Hast du mal drüber nachgedacht, die Kommunikation über ein Socket stattfinden zu lassen? Ich versuche das momentan für eine Java-Ruby-Schnittstelle (JRuby ging nicht) und gehe davon aus, dass das der sinnvollere Weg ist. Wenn deine Befehle sowieso schon Strings sind, dürfte das doch eine akzeptable Lösung sein, oder?
__________________ Patrick Gotthardts Weblog. |
| | |
| | Nach oben #10 | ||
| Erfahrener Benutzer Registriert seit: 27.02.2006
Beiträge: 159
|
Hallo Nummerchen, Zitat:
Wenn ich es richtig verstanden habe, hast Du das Java-Programm und die C#-Gui nebeneinander laufen? Warum lässt Du sie nicht per Netzwerk lokal miteinander kommunizieren? Wenn letztendlich nur Strings ausgetauscht werden, ist das nicht nur eine vernünftige Lösung, es besteht sogar die Möglichkeit, Java/CAD-Backend vom C#-CAD Frontend zu trennen, vorausgesetzt, man sichert die Kommunikaton miteinander ab (Verschlüsselung). Zitat:
Wie gesagt ... Socket-Kommunikation ... ohne JNI, das wäre hier mit Mörser auf Tauben schießen .... irgenwie wird man schon was treffen. Gruß, Jumper, the II. PS: Für eine Diplomarbeit ist es durchaus sinnvoll, in einer Vorbetrachtung verschiedene Lösungsansätze darzustellen und zu bewerten, um dann eine weier zu verfolgen | ||
| | |
| | Nach oben #11 |
| Wikinger Registriert seit: 02.03.2006 Ort: Aachen
Beiträge: 189
|
Ich würde auch Vorschlagen die Kommunikation über Sockets laufen zu lassen. Sowohl Java als auch C# haben schöne High Level APIs für Netwerkprogrammierung, mit einem einfachen Datenformat (JSON oder XML oder YAML oder was dir am liebsten ist) welches beide Sprachen lesen können, kann man dann sehr fix eine einfache Kommunikation aufbauen.
|
| | |
| | Nach oben #12 |
| Neuer Benutzer Registriert seit: 19.11.2008
Beiträge: 10
|
Also über Sockets oder über Files ist das ganze sicher auch nicht so einfach wie sich das in der Theorie anhört, da warten nähmlich viele Stolpersteine, die es auch nicht gerade einfacher machen. Ich würde Dir Vorschlagen Dich mit Java Applikcation- servern wie z.B GlassFish, Geronimo oder JBoss zu beschäftigen. Die drei lassen sich auch in einer sehr abgespekten Variante beteiben, bei Leistungsbedarf aber ohne weiteres hochrüsten und gut skalieren. Der Weg der mir vorschwebt wäre wie folgt: Du nimmst den GlassFish als EJB Containerserver und definierst Dir ein SessionBean, das die SQL-Datenbankabfragen via JDBC regelt. Dann definierst Du ein normales, Standard Remoteinterface für dein SessionBean, so dass man es an dieser Stelle schon mal von jedem exbliebingen Javaprogramm im Netz ansprechen kann. Der nächste Schritt ist es, daß ganze für C# Sichtbar zu machen und dafür definierst Du Dir einfach eine SOAP Webservice Definition am GlassFish Appserver (ist nur eine XML-Datei) so das der entfernte Zugriff für C# mittels Webservice funktioniert. Nun stehen Dir im C# sämmtliche, entfernte Funktionen auf entfernten Server zur verfügung Der Vorteil ist, das Du Dich weder mit Sockets oder XML/Json großartig rumschlagen musst, da Du auf C# Seite vollständige OOP arbeiten kannst. Um das entwickeln zu können benötigst Du eine vernünftige IDE z.B das NetBeans AllInOne GlassFish Bundle und kannst sofort loßlegen und das gibt es hier: http://www.netbeans.org/downloads/index.html Nimm das große Paket mit 250 MB große, da ist alles drin, auch Samples. |
| | |
| | Nach oben #13 |
| Erfahrener Benutzer Registriert seit: 27.02.2006
Beiträge: 159
|
Hallo marc, m.E. sind in einer J2EE Lösung genausoviele Stolpersteine enthalten, halt nur andere. Wenn man bereits entsprechende Vorkenntnisse hat, bietet es sich durchaus an. Andererseits ist die Frage, ob neben der Datenbank in Java noch ein J2EE Server für die SOA Schnittstelle erforderlich ist. Letztendlich ist es eine Frage der Gesamtlösung. Ich kann mir auch gut vorstellen, dass man mit ADO.NET und einen SQL Server auf .NET Basis ohne Java hier auskommt. Das Auslesen der Daten kann mit Sicherheit auf C# portiert werden und das ganze wäre wirklich einfach. Ob es allerdings das Verständnis für JNI verbessert, ist eine andere Frage. Ich finde es ja nett, wenn ich zu Winterreifen für mein Auto die Beratung bekomme, dass der Jepp das bessere Auto für das Gebirge wäre ... allerdings hilft es mir nicht, mit meinen vorhandenen Wagen dahin zu kommen. Daher frage ich da weiter nach Winterreifen für mein Auto und freue mich, wenn ich erst einmal Tipps für die Felgen dazu bekomme .... uzwar sinnvolle Tips Gruß, Jumper, the II. |
| | |
| | Nach oben #14 |
| Neuer Benutzer Registriert seit: 19.11.2008
Beiträge: 10
|
Deine Vergleiche scheinen immer etwas zu hinken, denn wenn Du Dich informiert hättest, wüsstest Du, das auch Microsoft für die Interoperatibilität mit anderen Sprachen und verteilten Systemen SOAP Webservices empfiehlt (die haben es schließlich auch erfunden und die Java Welt hat diesbezüglich nachgezogen). Ausserdem hast Du geschrieben, das Du Java und .NET verbinden willst. Wenn Du die Bedingungen jetzt im Nachhinnein änderst und aufeinmal von C# only redest, ist deine ganze Eingangsfrage hinfällig geworden. |
| | |
| | Nach oben #15 |
| Wikinger Registriert seit: 02.03.2006 Ort: Aachen
Beiträge: 189
|
Wenn ich das richtig verstanden haben will er doch nur Befehle aus C# in seiner Java Anwendung verarbeiten. Und diese Befehle bestehen größtenteils aus Strings. Also das ist mit Sockets doch wirklich nicht sehr aufwändig.
|
| | |
| | Nach oben #16 | |
| Neuer Benutzer Registriert seit: 19.11.2008
Beiträge: 10
| Zitat:
Glaubst Du? Nun ja, was hätten wir denn da alles? Blocking / NonBlocking? Threadsafe / non Threadsafe? Multiuser Access / Singleuser Access mit locking? Encodingfragen / oder am besten keine Umlaute? Streaming / NonStreaming? Implementierung von Client Socker UND Server Socket Definition des Protokolls Tokernizer schreiben um die Commandtokens zu parsen. Ach ja, .NET läuft unter Windows und damits auch als Netzwerkdienst läuft (ohne Userlogin) muss man das ganze in einem Windows Service für den Netzwerklayer programmieren - da stehen einem aber dann auch nur begrenzte API's zur verfügung und vor allem Das testing ist ein Riesensspass und eine Beschäftigung für Vollzeitteletubbies: a) /register blub_service.exe /net start blub /net stop blub /unregister blub.exe b) Ah! Fehler bemerkt, kompiliert gehe zu a) Ok,zugegeben mit Lowlevel C wäre noch ätzender. Aber wenn man nicht komplett male in der Rübe werden will, dann nutzt man einfach das, worauf sich die Industrie für solche Dinge geeinigt hat, API's die man nur nutzen muss. C# via SOAP- Komunikation mit Java. In C# habe ich einen Webservice Import Wizzard, der die entfernten Funktionen und Prozeduren fix und fertig in mein Programm einbettet, ohne das ich mich mit dem ganzen Lowlevelkram auseinandersetzen muss. Geändert von marc9022 (28.11.2008 um 11:21 Uhr) | |
| | |
![]() |
| Lesezeichen |
| Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
| Themen-Optionen | Thema durchsuchen |
| |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Probleme mit der Erreichbarkeit - nur bei 1und1? | Jann Hendrik | Ankündigungen | 67 | 09.06.2008 10:19 |
| Probleme mit Strato / Arcor? | MrNiceGuy | Plauderecke | 15 | 28.12.2006 23:35 |
| Caching mittels dbm-Dateien, Probleme mit dba_popen() | Ben | PHP-Programmierung | 4 | 27.07.2006 13:23 |
| Sourcecode von Klassen aus Java Native Interface (JNI) | xyz | Allgemeine Java-Programmierung | 0 | 22.11.2005 10:21 |
| Layout Probleme | VipViper2000 | Desktop-Applikationen und Grafik | 8 | 13.09.2005 22:35 |