Java won't call the functions from the .dll created using swig

I had created the dynamic library for java using swig and cmake for learning purposes. I can't call a function in java from the same libary that I created. The swig doc told me this is the result of forgeting to compile and link the swig wrapper file to my native libary, but I'm very sure that I did that with cmake build.

CMakeList.txt

cmake_minimum_required (VERSION 2.6)

FIND_PACKAGE(SWIG REQUIRED)
find_package(Java REQUIRED COMPONENTS Runtime Development)
find_package(JNI REQUIRED)
INCLUDE(${SWIG_USE_FILE})
set(JAVA ${java_include_path} )
INCLUDE_DIRECTORIES(${JAVA} ${JAVA}/win32)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET_SOURCE_FILES_PROPERTIES(hello.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(hello.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(hello java hello.i  hello.cpp)
SWIG_LINK_LIBRARIES(hello ${Java_LIBRARIES} ${JNI_LIBRARIES} ${CMAKE_CURRENT_SOURCE_DIR})

hello.cpp

#include "hello.hpp"

int adding(const int x, const int y)
{

  return y + x;
}

hello.hpp

int adding(const int x, const int y);

hello.i

 %module hello
 %{
   #include "hello.hpp"
 %}
int adding(const int x, const int y);

Can anyone tell me what I"m doing wrong when I'm creating the dynamic library? Thank you for the assistance.

The reason why I know this is due to this error message in eclipse

Exception in thread "main" java.lang.UnsatisfiedLinkError: hello.helloJNI.adding(II)I
    at hello.helloJNI.adding(Native Method)
    at hello.hello.adding(hello.java:14)
    at hello.Main.main(Main.java:14)

Which is the same kind of error message that the docs talk about.

Upvotes: 0

Views: 164

Answers (1)

The missing symbol in your error message is part of the JNI wrapper, not part of your library itself.

Usually this means that you've not called System.loadLibrary() for the native part of the SWIG module, before making the first call into it. Your CMake file looks like you've correctly linked the implementation, so it's not the error case you referred to from the documentation.

As well as manually calling:

System.loadLibrary("hello"); // The name of your DLL here

from your main method I like to use the following in my SWIG interface files when I'm targeting Java:

%pragma(java) jniclasscode=%{
  static {
    try {
        System.loadLibrary("hello"); // The name of your DLL here
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library failed to load. \n" + e);
      System.exit(1);
    }
  }
%}

This causes the native library to be loaded automatically before it is needed, which seems most natural to Java programmers.

Upvotes: 1

Related Questions