3

I have a custom dll that I access from Java using JNA. So far all is working perfect. Now however I would like to create Java classes from my C code. I assume this can't be done with JNA so what I did is to create a JNI method but this leads me to UnsatisfiedLinkError's. So my question is: Can I mix JNA and JNI when accessing the same DLL and if so, how should I go about doing that?

Hannes de Jager
  • 2,903
  • 6
  • 37
  • 57
  • 1
    Perhaps another approach is wrapping your class invocations with opaque pointers (like this: http://stackoverflow.com/questions/1873194/jna-calling-methods-upon-c-instance-passed-back-from-dll/1881197#1881197) – Mark Elliot Apr 20 '10 at 06:26

2 Answers2

4

Of course can you mix access to the DLL, since it is only loaded once anyway. The problem is how the linking to your application works:

JNA:

When using JNA you call the native functions of the jna library, which by some kind of reflection bind to the functions in your DLL. This has the advantage that you don't have to worry about the name of the functions in the DLL, they don't have to meet any conventions.

JNI:

Simple works by a mapping from your java classes to method names which are expected in the DLL. If you have a Class com.company.SomeClass containing a function int doStuff(int i, long john) with this signature:

JNIEXPORT jint JNICALL Java_SomeClass_doStuff(JNIEnv *env, jint i, jlong john) {
    return ...whatever...
}

If this function is missing, you get the UnsatisfiedLinkException.

Solution:

Since it seems you have written your own DLL, just add the functions required as wrapper functions, and you are done. To get the function signatures, you can create a header file automatically with the javah command.

I recommend reading Advanced Programming for the Java 2 Platform - Chapter 5: JNI Technology.

Daniel
  • 27,718
  • 20
  • 89
  • 133
0

I want to add one thing to do that. Don't forget extern "C" for each JNIEXPORT and also function for JNA.

As a simple example:

// Example DLL header file MyDLL.dll
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

extern "C" {
   MYDLL_API void HelloWorld(void);    
}

extern "C" {
   JNIEXPORT void JNICALL Java_MyJavaMain_HelloWorld(void); 
}

//Example CPP file MyDLL.cpp
#include "MyDLL.h"
#include "stdio.h"

extern "C" declspec(dllexport)

void HelloWorld(void){
    printf("Hello World From Dll");
}
Mustafa Kemal
  • 1,292
  • 19
  • 24