# Accessing a third party DLL through Java



## PoRL (Jul 21, 2008)

Hi all
I did a quick search through this forum, but couldn't see if this question has been asked before. Apologies if it has!

I'm trying to do a project to help a handicapped kid, and I'd like to write the controlling code in Java. (I would class my level of knowledge as "intermediate"). The problem is that I'm trying to access a usb connected DMX controller to control some lights. Put simply, you assign a value of 0 - 255 to a channel (0 - 512 max) to change the brightness of a colour, etc.

For this, the manufacturer has supplied a DLL, "K8062D.DLL". This is stateless, and has four methods: StartDevice, StopDevice, SetChannelCount(Count: Longint) and (most importantly!) SetData(Channel : Longint; Data : Longint). (Please note that I do not have the source code for this DLL)

How would I implement this such that I have a Controller Class providing access to these methods (eg "Controller.setData(1,124);")?

I tried googling this and basically got pointed at the "Java Native Interface" which went _spectacularly_ over my head!!

Any help would be really, really, really appreciated.

PoRL


----------



## thingamajig (Mar 5, 2005)

You found the correct technology. You do not call the API methods directly from Java. You write a C function which calls the methods that includes jni.h. Basically, you will want to write one c function for each method you need access to in the library. You don't need the source of your dll. Try following the instructions for the "hello world" version of this.

http://java.sun.com/docs/books/jni/html/start.html#769

I am leaving the office for now but can look at this in more depth tomorrow.

Confirm that your functions are of the form

void StartDevice();
void StopDevice();
void SetChannelCount(long);
void SetData(long, long);

Is there no method to get the value?


----------



## PoRL (Jul 21, 2008)

HI Thingamajig, and thanks for a really comprehensive response.

I can see the show-stopper now... Writing and implementing the c function isn't a "do-er" for me, I'm afraid, as my knowledge of c is best classed as "non-existent", and I've no access to a c-compiler even if it wasn't.

Thanks anyway, but just to close things off: These methods do indeed all return void (exactly as stated) since they're controllers, and there's no way of interrogating the current channel status.


----------



## thingamajig (Mar 5, 2005)

That shouldn't be a show stopper. The c is trivial and you can download the compiler. I can write that up fairly quickly.


----------



## thingamajig (Mar 5, 2005)

Here is your Java class for the controller methods, Controller.java


```
[SIZE="4"]
public class Controller {
    private native void startDevice();
    private native void stopDevice();
    private native void setChannelCount(long i);
    private native void setData(long i, long j);
    
    static {
        System.loadLibrary("Controller");
    }
}[/SIZE]
```
And here is your C code


```
[SIZE="4"]
#include <jni.h>
#include "Controller.h"

JNIEXPORT void JNICALL 
Java_Controller_startDevice(JNIEnv *env, jobject obj) {
    StartDevice();
    return;
}

Java_Controller_stopDevice(JNIEnv *env, jobject obj) {
    StartDevice();
    return;
}

Java_Controller_setChannelCount(JNIEnv *env, jobject obj, jlong i) {
    SetChannelCount(i);
    return();
}

Java_Controller_setData(JNIEnv *env, jobject obj, jlong i, jlong j){
    SetData(i,j);
    return();
}[/SIZE]
```
The procedure is as follows:

(1) Compile your java class

> javac Controller.java

(2) Create the header file for your C wrapper

> javah -jni Contoller

(3) Download Visual Studio Express C++ to get the MS compiler. Then compile the C code (http://msdn.microsoft.com/en-us/library/ms235639(VS.80).aspx)

> cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD Contoller.c -FeContoller.dll

(4) Build the program that will instantiate your Controller class and compile it.

> javac Main.java

(5) Make sure your Controller.class and Controller.dll are both in, e.g., your current directory. Then you are ready to go

> java -Djava.library.path=. Main


----------



## thingamajig (Mar 5, 2005)

Correction, you need to change the access to public in your Controller Class or write public Java methods to wrap the native.


----------

