Rich Oliver
Rich Oliver

Reputation: 6109

Scala native methods in inner classes

I have:

class XCClass
{   
  @native protected def createWin(displayPtr: Long, width: Int, height: Int, backGroundColour: Int = white.value,
    borderColour: Int = darkblue.value, borderWidth: Int = 0, xPosn: Int = 0, yPosn: Int = 0): Long
  @native protected def xOpen(): Long  
  System.load("/sdat/projects/prXCpp/Release/libprXCpp.so")  
//Code edited out

  class Window(width: Int, height: Int, backGroundColour: ColourInt = white, borderColour: ColourInt = darkblue,
    borderWidth: Int = 0, xPosn: Int = 0, yPosn: Int = 0)
  {
  val xWinPtr = createWin(xServPtr, width, height, backGroundColour.value, borderColour.value, borderWidth, xPosn, yPosn)
  @native def drawLine(x1: Int, y1: Int, x2: Int, y2: Int): Unit
  }
}

The first two methods work fine, but the native method on the inner class gives

object XApp extends App
{
  val xc:XCClass = XCClass()  
  val win: xc.Window = xc.Window(800, 600)
  win.drawLine(20, 20, 40, 40)
  readLine()  
}

Exception in thread "main" java.lang.UnsatisfiedLinkError: pXClient.XCClass$Window.drawLine(IIII)V

Here's the C++ signature

extern "C" JNIEXPORT void JNICALL Java_pXClient_XCClass$Window_drawLine(JNIEnv * env, jobject c1, Display *dpy,
    Window win, jint x1, jint y1, jint x2, jint y2)

I tried using an underscore instead of the $ sign, and having no inner name at all but that failed as well.

Edit2: I managed to get javah to work just before seeing Robin's answer and it gave

JNIEXPORT void JNICALL Java_pXClient_XCClass_00024Window_drawLine
  (JNIEnv *, jobject, jint, jint, jint, jint);

Edit4: It worked fine once I'd corrected errors in my code. It seems that the JVM will import a native function with the wrong parameter signature as long as the name is correct.

Upvotes: 3

Views: 707

Answers (1)

Robin Green
Robin Green

Reputation: 33083

I just did a quick test with a .java file and javah, and a $ is represented as _00024.

Upvotes: 6

Related Questions