Java using dll files

How to call/invoke external DLL library method/function from Java code?

Java’s JVM allows you to do many smart things but sometimes you may be forced to directly use external library or writing code in pure java would be very time-consuming comparing it with something more low-leveled. I stumbled upon such a problem and had to use a .dll driver from a hardware provider. Of course I googled it and didn’t find much info, and what I’ve found mostly concerned about JNI (Java Native Interface). I would like to tell you about JNA which is fast and simple to use in aforementioned task.

So, how does it work? The only thing you have to do is to download and import JNA (Java Native Access) to your project and write a simple class.

Hereunder you can analyse a simple Java program which uses a sample .dll. You can download my java code and .dll library sources later.

Java code:

package jnahelloworldtest; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Platform; import com.sun.jna.*; /** Simple example of native library declaration and usage. */ public class Main < public interface simpleDLL extends Library < simpleDLL INSTANCE = (simpleDLL) Native.loadLibrary( (Platform.isWindows() ? "simpleDLL" : "simpleDLLLinuxPort"), simpleDLL.class); // it's possible to check the platform on which program runs, for example purposes we assume that there's a linux port of the library (it's not attached to the downloadable project) byte giveVoidPtrGetChar(Pointer param); // char giveVoidPtrGetChar(void* param); int giveVoidPtrGetInt(Pointer param); //int giveVoidPtrGetInt(void* param); int giveIntGetInt(int a); // int giveIntGetInt(int a); void simpleCall(); // void simpleCall(); >public static void main(String[] args) < simpleDLL sdll = simpleDLL.INSTANCE; sdll.simpleCall(); // call of void function int a = 3; int result1 = sdll.giveIntGetInt(a); // calling function with int parameter&result System.out.println("giveIntGetInt("+a+"): " + result1); String testStr = "ToBeOrNotToBe"; Memory mTest = new Memory(testStr.length()+1); // '+1' remember about extra byte for \0 character! mTest.setString(0, testStr); String testReturn = mTest.getString(0); // you can see that String got properly stored in Memory object System.out.println("String in Memory:"+testReturn); Memory intMem = new Memory(4); // allocating space intMem.setInt(0, 666); // setting allocated memory to an integer Pointer intPointer = intMem.getPointer(0); int int1 = sdll.giveVoidPtrGetInt(Pointer.NULL); // passing null, getting default result System.out.println("giveVoidPtrGetInt(null):" + int1); // passing int stored in Memory object, getting it back int int2 = sdll.giveVoidPtrGetInt(intMem); //int int2 = sdll.giveVoidPtrGetInt(intPointer); causes JVM crash, use memory object directly! System.out.println("giveVoidPtrGetInt(666):" + int2); byte char1 = sdll.giveVoidPtrGetChar(Pointer.NULL); // passing null, getting default result byte char2 = sdll.giveVoidPtrGetChar(mTest); // passing string stored in Memory object, getting first letter System.out.println("giveVoidPtrGetChar(null):" + (char)char1); System.out.println("giveVoidPtrGetChar('ToBeOrNotToBe'):" + (char)char2); >>

Mappings table

Not every native type maps directly to Java type, furthermore a class representing pointers had to be introduced. You can read a handy type mapping table below:

Читайте также:  Cfg hacked css v34
Native Type Size Java Language Type Common Windows Types
char 8-bit integer byte BYTE, TCHAR
short 16-bit short short WORD
wchar_t 16/32-bit character char WCHAR, TCHAR
int 32-bit integer int DWORD
int boolean value boolean BOOL
long 32/64-bit integer NativeLong LONG
long long, __int64 64-bit integer long
float 32-bit FP float
double 64-bit FP double
char* C string String LPTCSTR
void* pointer Pointer LPVOID, HANDLE, LPXXX

Downloads:

  • DLLVisual Studio source project – ready to use Visual Studio 2010 project. You can alter it to continue experimenting with invoking DLL methods of library attached to the Netbeans project.
  • Netbeans project – ready to use NetBeans 6 project using example code explained in this article with appropriate jars and DLL library attached
  • JNA library jars – link to official JNA libraries download page

DLL library C++ functions source :

#include "simpleDLL.h" #include using namespace std; namespace simpleDLLNS < char simpleDLL::giveVoidPtrGetChar(void* param) < if(param != 0) < char* paramChrPtr = (char*)param; return *paramChrPtr; >else < return 'x'; >> int simpleDLL::giveIntGetInt(int a) < return 2*a; >void simpleDLL::simpleCall(void) < int x = 3; return; >int simpleDLL::giveVoidPtrGetInt(void* param) < if(param!=0) < int* x = (int*)param; return *x; >else < return -1; >> >

More from my site

How to capture content of eclipse Console window (web tomcat application)?

65 Comments

[…] of Memory and Pointer JNA objects. Example covering such case is provided in my another article: How to call/invoke external DLL library method/function from Java code? JNA, Java, Programmingjava, JNA, native code ← How to call/invoke external DLL library […]

Thank you soo much. took me a WHOLE day to find this post. Lots of examples of using JNA but none that shows exactly how it will be done in Real Life. you Polish guys are amazing! Dzienki! Will call u for beer when I come to poland next time!

hahaha, thank you for appreciating my content. I’ll keep your word about the beer, but linking me will be also good for now in favour 🙂

Did u see that I posted this article on dzone? Check here http://www.dzone.com/links/real_world_example_call_dll_from_java_with_visual.html You should have more hits today….lol

didn’t check my stats today. thank you very much! 😉
nice news about javaFX redist btw, thought there’s no hope about it

Hi Michal This is the best one page example of using JNA I have found so far. Got me started in about 5 minutes, regretfully, I got stuck in next 5 minutes 🙁 🙁 Here are immediate 2 issues:
(1) Does JNA handle mangled names? What I have is the DLL and the interface definition (ie. header files). The problem is that the function defined as
int* func(int) is mangled to int* _func@4(int) and Java does not like the ‘@’ in the name of the method. (2) Callbacks. The native lib uses them all over the place. In C++ it is easy. DLL provides the interface to define callbacks, so all the app has to do is to create them and pass the pointer to the API. When the event which has the associated callback occurs, the C++ app gets the information. Can something the same be done between the app written in Java and the DLL?

Читайте также:  Curl php для чайников

I am new to Java and I find using the compact style documentation like those two a bit difficult, hence my search for sample code. I looked at some callback samples and I do not see how I can bind my own callback method (written in Java) with the DLL. All I have in the DLL is the API to specify the callback by feeding in the pointer to the callback function. Does this mean that the callback must be a C function?

I’m not sure I fully understand you. Are you trying to invoke Java class method from native library passing this Java method as a Callback? I didn’t deal seriously with callbacks in Java although this looks like interesting discussion about your problem
Callbacks in Java JNA : http://stackoverflow.com/questions/5205654/c-callback-with-jna-makes-jre-crash Was link about solving problems with Mangled names in JNA helpful for you?

Hi there, I am new to accessing DLLs from Java using JNA. I need to access a methods from a class within the DLL and can not do this by just calling the library as I can seem to work out how to access a class I.e. the DLL is called CDrawControl.dll, but the class within the DLL I need to access is DrawCtl. So I need to get and instance of the DrawCtl class.
So all in all, how to I reach this method in the DLL? ie CDrawControl.DrawCtl.SaveFile() It is probably something very simple I am missing.Thanks for your help in advance.

I have only tried JNA with direct functions mapping, I am not really sure if what you need to do is possible using JNA or maybe you have to use JNI.. Official JNA documentation is now here: https://github.com/twall/jna Please let me know if you solve your problem, it’s interesting 😉

Hi Michal, Nice job, simple strait example for JNA utilization, thanks for your effor, easing ours 😉
I am trying to demo run your samle program, I am through most of the hurdles (configuring library path, various java.lang.UnsatisfiedLinkError), Now struck at error “Unable to load library ‘simpleDLL’: The specified module could not be found.” please guide me through this abt how to resolve this. Regards, Mithun PG

Читайте также:  Си шарп вычисление суммы чисел

Hi Even I am also getting the same error “module could not be found” if you found the solution please let me know.

Hi there and thanks for an excellent tutorial. There seems to be one “bug” in that the “unsatisfiedlinkerror” that I also get may be related to the missing file MSVCR100D.dll, see this link on how to integrate the file statically at compile time:
http://www.rhyous.com/2010/09/16/avoiding-the-msvcr100-dll-or-msvcr100d-dll/. I used the utility DEPENDENCY WALKER to detect this. So Visual Studio must either be installed, or linked in. -Carl

Greats, but I have is error Exception in thread “main” java.lang.UnsatisfiedLinkError: Unable to load library ‘simpleDLL’ and the library is the current folder.

Not sure what I’m doing wrong. Have an even simpler example. Can’t find the methods at runtime. Is there any problem using Netbeans / mingw compiler? QnAudio.cpp, compiled to a dll which is found by the java program: #include
#include “QnAudio.h” using namespace std; namespace QnAudioNS
< int QnAudio::getData(int i) return data[i];
> void QnAudio::setData(int i, int input) data[i] = input;
>
>; Guts of the java program: public class NewFrame extends java.awt.Frame < public interface QnAudio extends Library QnAudio INSTANCE = (QnAudio) Native.loadLibrary(
“C:/Documents and Settings/Al Gerheim/My Documents/NetBeansProjects/QnAudio/dist/Debug/MinGW_TDM-Windows/libQnAudio”,
// “libQnAudio”,
QnAudio.class); int getData(int i);
void setData(int i, int input);
> public static void main(String args[]) < QnAudio qn_Audio = QnAudio.INSTANCE; qn_Audio.setData(0, 1); // error at this statement, function not found.
qn_Audio.setData(1, 5);
qn_Audio.setData(2, 10); int i = qn_Audio.getData(0);
i = qn_Audio.getData(1);
i = qn_Audio.getData(2);
i = 1000; >
>

HI i am getting the following exception when invoking the external DLL file. Exception in thread “main” java.lang.UnsatisfiedLinkError: Unable to load library ‘C:/Users/kumargud/Desktop/JNA/simpleDLL/’: The specified module could not be found.

Hi,
i have a c dll method in which the function signature is: int func(HANDLE handle, char *Info);
The parameter [out]Info is an output parameter. Could you let me know how to call this function. I tried using Callback in jna but not able to get the proper value of info.
I m using jna to call this function.

Hello! Did you try to run this with 64-bit DLL? Weird, because I can’t transmit parameter from java code to C method (in dll), but I can get the return value in java code from dll methods.

Источник

Оцените статью