Wrap DLL in Java

I have code for talking to a hardware device in windows running C ++. The code does something fairly simple to respond to a button click on the device, and I compiled into a dll with an observer that gets called when the button is pressed. Now I need to associate this with a large Java program.

I was going to use JNA, but it only works with C, and I don’t see how to do it with the Observer pattern in C. I studied the use of BridJ and SWIG (both of which cliam for working with the C ++ DLL) to create an interface for the compiled dll (with the corresponding header file), but BridJ creates a huge number of files (in JNAeratorStudio), and then stops with an error, and I don’t see how to get started with Windows using SWIG (I use Visual Studio Express, not the full Visual Studio).

Does anyone know a tutorial on integrating a C ++ DLL with a Java program - SWIG looks pretty promising, but the tutorials are "marshy."

I added some simple C codes to talk to the DLL below:

#include <iostream> #include <stdio.h> #include "DeepFocusControlDll.h" using namespace std; using namespace DeepFocusControl; class MyObserver : public DeepFocusControl::DeepFocusObserver{ void Event(){ printf("***Button Pushed***"); } }; int main() { DeepFocusControl::AVA6Control* dfc = new DeepFocusControl::AVA6Control(); MyObserver* observer = new MyObserver(); dfc->AddObserver(observer); bool connected = dfc->IsConnected(); printf("Connected %s\n", (connected)?"true":"false"); bool connectresult = dfc->Connect(); printf("Connecting %s\n", (connectresult)?"true":"false"); connected = dfc->IsConnected(); printf("Connected %s\n", (connected)?"true":"false"); dfc->SetHardwareAppLaunch(false); char waitChar; cin >> waitChar; dfc->SetHardwareAppLaunch(true); dfc->RemoveObserver(observer); dfc->Disconnect(); printf("Disconnected\n"); cin >> waitChar; } 

If anyone knows an easier way to use the observer pattern on this, I can happily recode side C.

0
source share
1 answer

Looks like you're looking for a SWIG directorial feature . In your simplest form, you can use directors with SWIG by providing an interface file, for example:

 %module(directors=1) MyModule %feature("director"); %{ #include "mydll.h" %} %include "mydll.h" 

Given the header file "mydll.h":

 class Observer { public: virtual void frobination() = 0; virtual ~Observer() {} }; inline void bar(Observer *o) { o->frobination(); } 

Then you can run SWIG:

  swig -Wall -java -c ++ mymodule.i

This will create three Java classes: MyModule , MyModuleJNI and Observer . These MyModule will contain all the free functions from your header file, presented as static member functions, since Java does not have functions such as free functions. You can safely ignore MyModuleJNI - this is the glue generated by SWIG to connect MyModule to real C ++ implementations. You will need to compile mymodule_wrap.cxx for MyModuleJNI (and therefore MyModule ) to work correctly and load the DLL using System.loadLibrary before you call any functions from them.

The Observer class corresponds directly to the Observer interface in mydll.h . You must extract from it in Java and override the frobinate function to give it its own implementation:

 public class Test extends Observer { @Override public void frobination() { System.out.println("go go gadget frobinator"); } public static void main(String[] argv) { System.loadLibrary("mymodule"); Test t = new Test(); MyModule.bar(t); } } 

What can I compile and run to do exactly what you hoped.

If you want, you can automate the call to System.loadLibrary by adding:

 %pragma(java) jniclasscode=%{ static { try { System.loadLibrary("mymodule"); } catch (UnsatisfiedLinkError e) { System.err.println("Native code library failed to load. \n" + e); System.exit(1); } } %} 

into your SWIG interface file.

If your real header file is so simple, it should be just as easy to get the same results. If it is more complicated, you can instruct SWIG for a special occasion, some of its wraps in various ways.

+2
source

All Articles