Java – How to call a JNI DLL from C++

cclassdlljava-native-interface

I have a task to interface with a dll from a third party company using C++.

The dll package comes with:

  • the dll itself
  • a sample Java implementation – consists of a java wrapper(library) generated using the SWIG tool and the the java source file
  • documentation that states all the public datatypes, enumeration and member functions.

My other colleague is using Java(based on the example in package) to interface with the dll while I'm asked to use C++. The Java example looks straight forward… just import the wrapper and instantiate any class described in the docs..

More info on the dll:

  • From the docs, it says the dll was programmed using C++
  • From a hexdump, it shows that it was compiled using VC90 (VS C++ 2008 right?) and something from Dinkumware.
  • From a depends.exe output, the functions seems to be wrapped under JNI. For example: _Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect@20

My dilemma:

  • The dll company is not changing anything in the dll and not providing any other info.
  • How do i use the member functions in the class from the dll?
  • I did some simple LoadLibrary() and GetProcAddress and manage to get the address of the public member functions.
  • But i dunno how to use the functions that has the datatype parameters defined in the dll. For example:
    From the docs, the member function is defined as:

void Server::connect(const StringArray, const KeyValueMap) throw(std::invalid_argument,std::out_of_range)
typedef std::map Server::KeyValueMap
typedef std::vector Server::StringArray

how do i call that function in C++. The std::map and std::vector in my compiler (VS 2005) has different functions listing that the one in the dll. For example, from the depends.exe output:

  • std::map // KeyValueMap – del, empty, get, has_1key,set
  • std::vector // StringArray – add, capacity, clear, get, isEMPTY, reserve, set, size

Any advice/strategy on how i should solve this? Is it possible to simply instantiate the class like the Java example?

Best Answer

If you are trying to use VS 2005 to try and interface with a DLL that is built using VS2008, your attempts will be mostly doomed unless you can use a plain C interface. Given your description, this is not the case; The runtime libraries differ between VS2005 and VS2008 so there is little chance that the object layout has stayed the same between compilers. The 'something from Dinkumware' that you're referring to is most likely the C++ standard library as ISTR that Microsoft uses the Dinkumware one.

With your above example you're also missing several important pieces of information - the types you describe (Server::StringArray and Server::KeyValueMap) are standard library containers. OK fine, but standard library containers of what? These containers are templates and unless you know the exact types these templates have been instantiated with, you're a little stuck.

Is this DLL intended to be called from C++ at all? The fact that it export a JNI interface suggests that it might not be in the first place. Does it export any other public symbols apart from those that are of the format _Java_...?

Of course if there is no other way in and you must use C++ instead of Java, you might want to look into embedding a JVM into your C++ app and use that to call through to the C++ dll. It's not what I'd call an elegant solution but it might well work.