Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hi Tom,
danke für deine Antwort. Ich habe mir den Artikel angeschaut, bin aber leider auch damit noch nicht wirklich weiter gekommen.
Ich denke das Problem liegt darin, dass die ILSID als Pointer an die DLL übergeben werden muss. Die DLL schreibt dann die erzeugte ILSID direkt in den Speicherplatz, worauf der Pointer zeigt. Als Rückgabewert der DLL kommt nur ein "Fehlercode" zurück, ob das funktioniert hat oder nicht.
Also wie kann ich das implementieren, dass die DLL Zugriff auf den Speicherplatz einer Variable hat?
Ich habe versucht einfach eine int variable anzulegen und diese zu übergeben. Da bekomme ich folgende Exception:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:383)
at com.sun.jna.Function.invoke(Function.java:315)
at com.sun.jna.Library$Handler.invoke(Library.java:212)
at com.sun.proxy.$Proxy0.LSX_CreateLSID(Unknown Source)
at Dauerlauf.Dauerlauf.jButton1ActionPerformed(Dauerlauf.java:162)
at Dauerlauf.Dauerlauf.access$000(Dauerlauf.java:16)
at Dauerlauf.Dauerlauf$1.actionPerformed(Dauerlauf.java:56)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6297)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3275)
at java.awt.Component.processEvent(Component.java:6062)
at java.awt.Container.processEvent(Container.java:2039)
at java.awt.Component.dispatchEventImpl(Component.java:4660)
at java.awt.Container.dispatchEventImpl(Container.java:2097)
at java.awt.Component.dispatchEvent(Component.java:4488)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4575)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4236)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4166)
at java.awt.Container.dispatchEventImpl(Container.java:2083)
at java.awt.Window.dispatchEventImpl(Window.java:2489)
at java.awt.Component.dispatchEvent(Component.java:4488)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:674)
at java.awt.EventQueue.access$400(EventQueue.java:81)
at java.awt.EventQueue$2.run(EventQueue.java:633)
at java.awt.EventQueue$2.run(EventQueue.java:631)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$3.run(EventQueue.java:647)
at java.awt.EventQueue$3.run(EventQueue.java:645)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:644)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
BUILD SUCCESSFUL (total time: 5 seconds)
Hi Tom,
Ich denke das Problem liegt darin, dass die ILSID als Pointer an die DLL übergeben werden muss
Also wie kann ich das implementieren, dass die DLL Zugriff auf den Speicherplatz einer Variable hat?
Also einen Pointer "im C/C++-Sinne" kannst du von Java aus nicht erzeugen, da Java sowas schlicht und einfach nicht kennt!
So ganz spontan fällt mir dazu auch keine nette Lösung ein!
Man könnte per JNI vielleicht auf ein 'normales' C/C++-Programm zugreifen, dass den Wert dann in einen Pointer verwanderlt und an die DLL weiterreicht.
Klingt aber zugegebenermaßen nicht sehr elegant
Vielen Dank für eure Hilfe.
Jetzt funktioniert es bei mir!
Der Trick mit dem Pointer war es, in der Deklaration der Methode als Datentyp "IntByReference" zu wählen.
Das Interface zu der DLL sieht demnach so aus:
Java:
import com.sun.jna.*;
import com.sun.jna.ptr.IntByReference;
public interface TANGODLL extends Library {
public int LSX_CreateLSID(IntByReference ILSID);
public int LSX_ConnectSimple(int lLSID,int lAnInterfaceType,String pcAComName,int lABaudRate,boolean bAShowProt);
public int LSX_MoveRel (int lLSID,double dX,double dY,double dZ,double dA,boolean bWait);
public int LSX_Disconnect(int lLSID);
public int LSX_FreeLSID(int lLSID);
}
Das laden der DLL und aufrufen der Funktionen dann in dieser Form:
jetzt kommt das nächste Problem...
Und zwar möchte ich einfach nur, dass der Benutzer über ein Drop-Down Menü einen verfügbaren COM-Port wählen kann.
Dazu habe ich mir javax.comm runtergeladen und eingebunden und folgendes implementiert:
Java:
public static String[] ComPorts()
{
String[] Ports = new String[10];
int i = 0;
CommPortIdentifier serialPortId;
Enumeration enumComm;
enumComm = CommPortIdentifier.getPortIdentifiers();
while (enumComm.hasMoreElements()) {
serialPortId = (CommPortIdentifier) enumComm.nextElement();
if(serialPortId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
Ports[i] = serialPortId.getName();
i++;
}
}
return Ports;
}
Leider gibt "CommPortIdentifier.getPortIdentifiers()" Das enum danach bleibt leer und die while Schleife wird direkt übersprungen.
Nach etwas googlen habe ich dann gesehen, dass man die comm.jar, javax.comm.properties und die win32com.dll in entsprechende Ordner kopieren soll.
1. comm.jar nach jre\lib\ext
2. properties nach jre\lib
3. dll nach jre\bin
Jetzt sieht meine Ordnerstruktur so aus:
Ich habe alles im "jre1.8.0_45" Ordner entsprechend kopiert, aber es funktioniert leider nicht.
Aus einem anderen Forum sagte jemand, man solle die dll ins system32 Verzeichnis kopieren, aber auch das brachte leider nicht den Durchbruch.
Woher weiß ich denn welches jre oder jdk meine IDE benutzt und habt ihr noch Ideen, was ich machen kann, damit ich meiner COM-Ports auflisten kann?
(Und ja, es sind COM-Ports vorhanden )
Wenn ich externe JARs benutze, dann liegen die bei mir Projektordner unter libs, also würde ich da auch die comm.jar ablegen. Hab noch nie eine JAR im JRE oder JDK Verzeichnis abgelegt.
Wo die properties gesucht werden, läßt sich schwer erraten, vielleicht im gleichen Pfad wie die comm.jar. Aber vielleicht gibts auch Beispiele im Inet dazu?
Wo die dll-liegt, ist vermutlich egal, aber ich denke, du mußt die dll mit regsvr32 registrieren.
Wenn ich externe JARs benutze, dann liegen die bei mir Projektordner unter libs, also würde ich da auch die comm.jar ablegen. Hab noch nie eine JAR im JRE oder JDK Verzeichnis abgelegt.
Ich hab mal bischen gesucht ... nutzt du Windows oder Linux? Weder die javax.com noch rxtx scheint es noch für Windows zu geben und unter Linux wird auch RXTX empfohlen. Hab rxtx unter Windows mit Gradle versucht einzubinden, aber da gibts nur die JAR und die alleine reicht leider nicht. Kann es leider nicht weiter testen ...
Ok die win32com.dll ist unter windows7 nicht registrierbar (vermutlich weil 32bit?). Habs grad versucht. Da ich aber auch demnächst auf serielle Schnittstellen zugreifen muß, werde ich mal noch ein bischen suchen. Kann mir nicht vorstellen, daß es mit Java unter Windows 7 keine Möglichkeit geben sollte ...