Call system C function in Java/Scala

17 Sep 2015

Low level system functions are often written in C/C++. You can use Java Native Interface to call the C/C++ code in Java. A more common way is to use system library, such as .so files in Linux and .dll files in Windows, in Java. Here is an example of how to add glibc functions in Java/Scala.

Add Dependency

JNA is a third party library for Java. Add the dependency to your building tools. If you use sbt, add the following line:

libraryDependencies += "net.java.dev.jna" % "jna" % "4.0.0"

Import jna library in Source Code

import com.sun.jna._

Define the interface

trait in Scala is equal to interface in Java.

trait libc extends Library {
  def open(path:String, flag:Int):Int
  def ioctl(fd:Int, request:Int, args:Array[_]):Int
  def close(fd:Int):Unit
}

Load libc

val libc = Native.loadLibrary("c", classOf[libc]).asInstanceOf[libc]

Note: libxxx loaded by name “xxx”.

Call the function

Then, you will be able to call the lower system functions, such as open, read, write, close and ioctl.

val fd = libc.open(_file, 1)

Complete libc example

This is a complete libc example for scala. The library will load once when it is been used:

package org.janzhou.native

import com.sun.jna._

trait libc extends Library {
  def open(path:String, flag:Int):Int
  def ioctl(fd:Int, request:Int, args:Array[_]):Int
  def close(fd:Int):Unit
}

object libc {
  private var _libc:libc = null
  def run():libc = {
    if ( _libc == null ) {
      _libc = Native.loadLibrary("c", classOf[libc]).asInstanceOf[libc]
    }
    _libc
  }

  val O_ACCMODE    =   3
  val O_RDONLY     =   0
  val O_WRONLY     =   1
  val O_RDWR       =   2
  val O_CREAT      = 100
  val IOCTL_TRIM   = 0x1277
}

Source Code: https://github.com/janzhou/scala-native