# DLL in Java einbinden (Quelltext aus Excel VBA)



## Thomas Lorenz (16. Mrz 2011)

Hallo Gemeinde, 

in der Vergangenheit hatte ich mal ein Excelprogramm geschrieben, welches eine DLL-Datei eingebunden hat. 
Das läuft auch heute noch, also die DLL ist noch genauso zu verwenden.

Jetzt möchte ich in einer Java-Anwendung genau diese DLL verwenden.
Meine Frage ist erst einmal, ob ihr mir dabei helfen könnt diese DLL für Java startklar zu machen.
Den Code der VBA-Datei würde ich dann hier eintragen.

Vielleicht ist ja jemand in beiden Sprachen unterwegs und kann mir auf die Sprünge helfen, da ich so etwas
noch nie in Java gemacht habe.

Den DLL-Code habe ich nicht und komme auch nicht da ran. Die Daten dahinter sind massiv und werden auch
in unregelmäßigen Abständen geändert.


----------



## Murray (16. Mrz 2011)

I.A. kann man von Java aus nicht einfach beliebige DLLs einbinden (angeblich ermöglicht JNA das in manchen Fällen; damit habe ich aber keine Erfahrung). Normalerweise verwendet man eine eigene Wrapper-DLL. Dazu definiert man abstrakte Java-Methoden, die man native implementieren will, kennzeichnet sie mit dem Schlüsselwort native und generiert mit javah daraus ein Header-File. Dazu kann man dann in C die Methodenrümpfe implementieren, die dann wiederum die eigentlich einzubindende DLL verwenden.


----------



## Tomate_Salat (16. Mrz 2011)

wenn du funktionen (nicht zu verwechseln mit Methoden!) einbinden willst, ist das mit JNA recht einfach. Allerdings bin ich mir nicht sicher, wie und ob das mit Methoden geht. In dem Falle bräuchtets du, afaik, eine wrapper-dll. 

Wenn du (oder jmd anderes) eine Möglichkeit für Methoden (am besten noch in einem namespace) gefunden hat, würde mich auch interessieren, wie man diese ohne Wrapper mit JNA aufrufen kann.


----------



## Thomas Lorenz (17. Mrz 2011)

Danke für die Hinweise.
Zur näheren Erläuterung kann ich Folgendes sagen:

Die DLL bietet mir ein Fenster an, bei dem ich in ein Textfeld Buchstaben eintrage. Je mehr Buchstaben ich eintrage, desto weniger Ergebnisse bekomme ich in einer erscheinenden Tabelle angezeigt (das geht hier um ein Straßenverzeichnis einer Stadt).
Wähle ich eines der Ergebnisse aus schliesst sich das Fenster ---> Ende.


----------



## MarderFahrer (17. Mrz 2011)

Keine Ahnung ob das hier einfach nur eine falsche Bezeichnung ist, aber in diesem Beispiel ist die Rede von Methoden einer DLL, die mittels Java angesprochen werden ohne zusätzlich neue Header zu erstellen.


```
import java.nio.ByteBuffer;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.ptr.ByReference;
import com.sun.jna.ptr.IntByReference;


public class DLL  {

	// This is the standard, stable way of mapping, which supports extensive
	// customization and mapping of Java to native types.
	public interface Idll extends Library {
		
		//Path to the desired dll
		Idll INSTANCE = (Idll)Native.loadLibrary(("C:\\windows\\system32\\SCARD32.dll"), Idll.class);
		
		//declaration of methods from the dll that one wants to use in java(Must have identical name as the method inside the dll?)
		public int SCardComand(Long Handle, String cmd, Long CmdLen, String DataIn, Long DataInLen, ByteBuffer DataOut, Long DataOutLen);
		
		public int GetMeasuredValues(int portId, int in0, int in1, int in2, int in3, int in4, int in5, int in6, ByReference out0, ByReference out1, ByReference out2, ByReference out3, ByReference out4, ByReference out5, ByReference out6);
		    
	}

    public static void main(String[] args) {
        long Handle = 0;
        String cmd = "Card,Info,Status";
        //String cmd = "Card,MemRead,128,6";
        long CmdLen = 16; 
        String DataIn = ""; 
        long DataInLen= 0; 
        
        byte[] bytetest ;
        bytetest = new byte[50];
        long DataOutLen = 255;
    	        
       
        ByteBuffer bbin  = ByteBuffer.wrap(bytetest);
        
        IntByReference iref0= new IntByReference();        				
        IntByReference iref1= new IntByReference();
        IntByReference iref2= new IntByReference();
        IntByReference iref3= new IntByReference();
        IntByReference iref4= new IntByReference();
        IntByReference iref5= new IntByReference();
        IntByReference iref6= new IntByReference();
        

        try{
        	
        	int returnCode0 = Idll.INSTANCE.SCardComand(Handle, cmd, CmdLen, DataIn, DataInLen, bbin, DataOutLen);
        	if(returnCode0 != -1){
	        	String DataOut = Native.toString(bytetest); 
	        	System.out.println(bytetest);
	        	System.out.println(DataOut);
        	}
        	
        	
        	int returnCode1 = Idll.INSTANCE.GetMeasuredValues(0, 6, 3, 0, 0xFF, 0xFF, 0, 0, iref0, iref1, iref2, iref3, iref4, iref5, iref6); 
        	if(returnCode1 != -1){
	        	System.out.println("iref0 = " + iref0.getValue());
	        	System.out.println("iref1 = " + iref1.getValue());
	        	System.out.println("iref2 = " + iref2.getValue());
	        	System.out.println("iref3 = " + iref3.getValue());
	        	System.out.println("iref4 = " + iref4.getValue());
	        	System.out.println("iref5 = " + iref5.getValue());
	        	System.out.println("iref6 = " + iref6.getValue());
        	}
        	
        } catch(UnsatisfiedLinkError e){
        	e.printStackTrace();
        }
        
    }
}
```

Laut eclipse ist das kompilierbar. Aber da ich die DLL bzw. den dazugehörigen Kartenleser nicht habe kann ich nicht sagen ob das auch funktioniert.

Edit:
Ich sehe gerade, dass es sich hierbei offensichtlich um Funktionsaufrufe handelt. Hat entgegen des Comments nichts mit Methoden Calls zu tun. Fall es jemanden hilft, hier ist nochmal ein Beispiel, welches jeder ausprobieren kann. 


```
import com.sun.jna.Library;
import com.sun.jna.Native;

public class DLL  {

	// This is the standard, stable way of mapping, which supports extensive
	// customization and mapping of Java to native types.
	public interface Idll extends Library {
		
		//Path to the desired dll
		Idll INSTANCE = (Idll)Native.loadLibrary(("C:\\windows\\system32\\msvcrt.dll"), Idll.class);
		
		//declaration of methods from the dll that one wants to use in java(Must have identical name as the method inside the dll?)
		public int puts(String str);
	}

    public static void main(String[] args) {
    	
    	Idll.INSTANCE.puts("Test");
    	
    }
}
```

Die puts Funktion macht nichts weiter als einen String Output auszugeben. Also quasi System.out.print() mit Windows Mitteln. Funktioniert auch so bei mir. Wenn man also DLL's mit Business Logik Funktionen hat, kann man sich das re implementieren in Java sparen indem man sie auf diese Weise einfach aufrufen kann.


----------



## Tomate_Salat (17. Mrz 2011)

so baue ich meine Konstrukte, wenn ich funktionen aufrufen will, aber ich bezweifel sehr stark, dass ich damit Methoden aufrufen kann. Wahrscheinl. benötigt das Aufrufen von Methoden doch einen Wrapper, welcher mir die Objektinstanz(en) hält und ich diese Methoden dann über Funktionen aufrufe =(


----------

