I am trying to access this piece of c++ code through JNA library that is written in .dll file
bool Services::ReverseString(const std::wstring &strIn)
{
return true;
}
My scala code is written below
trait CoreServices extends Library{
def ReverseString(m:WString):Boolean
}
val librarypath = "somepath"
System.setProperty("jna.library.path", librarypath)
val libc = Native.load("Services", classOf[CDocuLinkCoreServices])
val x=libc.ReverseString(new WString("dddd"))
But I am getting the below error
java.lang.error invalid memory access
I am pretty new to JNA. ANy help will be appreciated.
I doubt you can call C++
code from Scala
without using C
style naming convention. I guess, the only way to go here is via extern "C"
wrapper
For the following project tree
.
|-- Makefile
|-- c
| `-- Services.cc
|-- jar
| `-- jna-5.4.0.jar
|-- lib
| |-- libServices.dylib
| `-- libServices.dylib.dSYM
| `-- Contents
| |-- Info.plist
| `-- Resources
| `-- DWARF
| `-- libServices.dylib
`-- scala
| `-- jna_call.scala
`-- target
and following code
Scala
import com.sun.jna.Library
import com.sun.jna.WString
import com.sun.jna.Native
trait Services extends Library {
def ReverseStringWrapper(m:WString) : Boolean
}
object JNA {
def main(args:Array[String]):Unit = {
println("Testin JNA!! ")
val librarypath = "./lib"
System.setProperty("jna.library.path", librarypath)
val libc = Native.load("Services", classOf[Services])
val x=libc.ReverseStringWrapper(new WString("dddd"))
println("Result: " + x);
}
}
where native code looks like this
C++
#include <string>
class Services {
public:
bool ReverseString(const std::wstring &strIn);
};
bool Services::ReverseString(const std::wstring &strIn)
{
return true;
}
extern "C" {
bool ReverseStringWrapper(const std::wstring &strIn)
{
Services s;
return s.ReverseString(strIn);
}
}
and library being built following way
> c++ -std=c++11 -g -shared \
-fpic -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/$(ARCH) \
c/Services.cc -o lib/libServices.dylib
while Scala
code is compiled following way
> scalac -d target -classpath "jar/jna-5.4.0.jar" scala/jna_call.scala
and executed this way
> scala -classpath "./target:jar/jna-5.4.0.jar" JNA
Testin JNA!!
Result: true
everything works as expected.
You can find full sample code here: https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo054