DLL einbinden und Serielle Kommunikation

TDO88

Grünschnabel
Hallo Zusammen,

ich mache gerade meine ersten Gehversuche in Java und möchte gerne eine DLL von einer Schrittmotorsteuerung einbinden, sodass ich die darin enthaltenen Funktionen benutzen kann.
Ich google jetzt schon seit 2 Stunden und bin leider noch nicht wirklich weiter gekommen. Ich habe zwar einiges von JNI und JNA oder sowas gehört, aber bisher leider noch nicht verstanden, wie das funktionieren soll. Ich hoffe mir kann da jemand helfen oder mir eine Anleitung dazu geben.
Des Weiteren wollte ich gerne eine serielle Kommunikation aufbauen. Dazu sollte die JavaComm API benutzt werden. Davon habe ich aber leider nur Versionen für Linux, usw. aber nichts für Windows gefunden.
Wie kann ich denn eine serielle Kommunikation aufbauen, bzw. was brauche ich dazu?

Ich nutze übrigens Netbeans 8.0.2

Danke und Gruß
TDO
 

sheel

I love Asm
Hi

zuerst gilt es einmal zu klären, welche Art von DLL das ist.
C / .NET? Evt. auch C++ oder sonstiges? 32/64bit?
Wenn du dir nicht sicher bist, lad sie vllt. hier im Forum rauf, damit wir sie anschauen können.
Hast du den ganzen Source dazu oder nur Header (.h-Dateien)? (oder gar nichts?)

Zu JavaComm, meinst du javax.comm?

Ist deine JRE 32 oder 64bit?
 

TDO88

Grünschnabel
Hi Sheel,

die DLL ist eine Standard C DLL. Ich habe Sie als 32 und als 64-Bit Version. Ich habe dazu die Header Datei.

Ja, ich meinte javax.comm!

JRE.... wie bekomme ich das raus?
Hilft das evtl. weiter?

Hat keiner einen Hinweis für mich?
 

Anhänge

  • NetBeansHelp.jpg
    NetBeansHelp.jpg
    105,6 KB · Aufrufe: 21
Zuletzt bearbeitet von einem Moderator:

sheel

I love Asm
Bild: Also eine 64bit JRE.

Zu zB. JNA hat sogar Wikipedia Beispielcode:
https://en.wikipedia.org/wiki/Java_Native_Access

a) com.sun.jna.* importieren

b) EIn Interface machen, das die Funktionen der DLL (sichtbar im header) auf Java abbildet und dabei von Library erbt)
Java:
public interface MeineDLL extends Library {
    public boolean blabla1 (int a, int b);
    public floatblabla2 (int c, int d);
}
Die Datentypenzurodnungen zwischen C und Java sind dabei in der Tabelle Mappings auf Wikipedia abgebildet.

c) Mit Native.loadLibrary die DLL laden

d) Vom zurückgegebenen Objekt die Funktionen aufrufen.
 

TDO88

Grünschnabel
Guten Morgen,

ich habe jetzt eine .java Datei erstellt mit folgendem Code:
Java:
import com.sun.jna.Library;

public interface TANGODLL extends Library {
    public int LSX_CreateLSID(int 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);
}

Was ich aber noch nicht verstehe... irgendwie muss man dem Programm doch noch den Pfad zur DLL übergeben oder muss die DLL an einem bestimmten Speicherort liegen?
Oder enthält der Native.LoadLibrary Befehl den kompletten Pfad zur DLL?
Kann ich den Native.LoadLibrary auch in meiner "Haupt.java" Datei aufrufen?

Vielen Dank soweit für deine Hilfe

TDO88
 

sheel

I love Asm
Ja, beim LoadLibrary kann man auch einen Pfad angeben.

Was du mit der Haupt-Datei meinst bin ich mir nicht sicher. Hast du außer dem Interface nur eine andere Java-Datei? Dann muss das dort aufgerufen werden, ja. Im Interface selber kann überhaupt kein ausführbarer Code stehen (also nur Methodennamen, Parameter, Returnwerte usw.)
 

TDO88

Grünschnabel
Ja, meine Struktur sieht bisher so aus:
50135-c3c6d50ec28e5fc7d033edf061279243.jpg


In der TANGODLL.java steht der oben gepostete Code.

Die Dauerlauf.java ist eine Anwendung mit Frontpanel.
Da habe ich einfach einen Button eingefügt und in dessen Event versuche ich auf die DLL zuzugreifen.
Dafür habe ich folgenden Code eingegeben:
Java:
String DLLPath = "C:\\Users\\TDO\\Documents\\NetBeansProjects\\Dauerlauf\\Tango_DLL.dll";
TANGODLL TANGOINST = (TANGODLL) Native.loadLibrary(DLLPath, TANGODLL.class);
int ILSID = -1;
int returnfunction = 0;
String Port = "COM14";
   
returnfunction = TANGOINST.LSX_CreateLSID(ILSID);

usw.

Dabei bekomme ich folgende Exception:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Invalid memory access

Woran kann das liegen?

:edit
Ich hab das ganze gerade nochmal im debug modus laufen lassen. Beim Aufruf der CreateLSID Funktion wird der Fehler wohl erzeugt. Die Funktion benötigt normalerweise einen Pointer auf die ILSID. So wie ich es bisher verstanden habe, gibt es in Java aber keine wirklichen Pointer und Variablen werden immer als Pointer übergeben. Ist das so richtig? Muss ich am Code für Pointer übergaben noch etwas beachten?
 
Zuletzt bearbeitet:

vfl_freak

Premium-User
Moin,

Die Funktion benötigt normalerweise einen Pointer auf die ILSID. So wie ich es bisher verstanden habe, gibt es in Java aber keine wirklichen Pointer und Variablen werden immer als Pointer übergeben
Nicht ganz, Java kennt nicht nur "keine wirklichen Pointer", sonder gar keine!!
Parameter immer per call-by-value übergeben!
Hier ist das mMn ganz anschaulich erklärt: http://blog.gungfu.de/archives/2005...y-value-und-call-by-reference/comment-page-1/

Ist denn "LSX_CreateLSID" eine Methode aus dem JNI oder aus der DLL, auf die Du zugreifen willst ??
Letzteres ging halt nicht direkt, sondern nur über eine im JNI gekapselt Methode !

Gruß Klaus
 

TDO88

Grünschnabel
Hallo Klaus,

"LSX_CreateLSID" ist eine Methode aus der DLL.
Ich versuche es auch über JNA und nicht über JNI, falls das einen Unteschied macht
 

vfl_freak

Premium-User
Moin,
"LSX_CreateLSID" ist eine Methode aus der DLL.
Ich versuche es auch über JNA und nicht über JNI, falls das einen Unterschied macht
ja, macht es schon, da Du dann im Unterschied zu JNI keinen plattform-spezifischen Code schreiben musst ;-)

Bin zwar kein JNA-Experte, aber vlt. könnten dir diese Links weiterhelfen:
https://jna.java.net/javadoc/com/sun/jna/Pointer.html
http://www.programcreek.com/java-api-examples/index.php?api=com.sun.jna.Pointer

Gruß Klaus