Skip to content

Instantly share code, notes, and snippets.

@kammoh
Created December 3, 2017 00:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kammoh/13b09b6f4b67de610dadc76434622a29 to your computer and use it in GitHub Desktop.
Save kammoh/13b09b6f4b67de610dadc76434622a29 to your computer and use it in GitHub Desktop.
jni-ffi examples in scala
import jnr.ffi._
import jnr.ffi.annotations.{Out, Transient}
import jnr.ffi.types.pid_t
import scala.util.Random
object SimpleFfi {
val libc = LibraryLoader.create(classOf[SimpleFfi.LibC]).load("c")
trait LibC {
@pid_t def getpid: Long
@pid_t def getppid: Long
def getlogin: String
def gettimeofday(@Out @Transient tv: Timeval, unused: Pointer): Int
}
final class Timeval(val runtime: Runtime) extends Struct(runtime) {
val tv_sec = new time_t()
val tv_usec = new SignedLong()
}
def main(args: Array[String]): Unit = {
println("pid=" + libc.getpid + " parent pid=" + libc.getppid)
println("login=" + libc.getlogin)
val runtime = Runtime.getRuntime(libc)
val tv = new Timeval(runtime)
libc.gettimeofday(tv, null)
println("gettimeofday tv.tv_sec=" + tv.tv_sec.get + " tv.tv_usec=" + tv.tv_usec.get)
}
}
import jnr.ffi.LibraryLoader
import jnr.ffi.Memory
import jnr.ffi.Pointer
import jnr.ffi.annotations.Delegate
import jnr.ffi.types.size_t
import java.nio.Buffer
import java.nio.ByteBuffer
import java.nio.ByteOrder
object Qsort {
trait Compare {
@Delegate def compare(p1: Pointer, p2: Pointer): Int
}
final class IntCompare extends Qsort.Compare {
override def compare(p1: Pointer, p2: Pointer): Int = {
val i1 = p1.getInt(0)
val i2 = p2.getInt(0)
if (i1 < i2) -1
else if (i1 > i2) 1
else 0
}
}
trait LibC {
def qsort(data: Array[Int], @size_t count: Int, @size_t width: Int, compare: Compare): Int
def qsort(data: Pointer, @size_t count: Long, @size_t width: Int, compare: Qsort.Compare): Int
def qsort(data: Buffer, @size_t count: Long, @size_t width: Int, compare: Qsort.Compare): Int
}
def main(args: Array[String]): Unit = {
val libc = LibraryLoader.create(classOf[Qsort.LibC]).load("c")
val n = 100
val numbers = Array.fill(n)(Random.nextInt(n*n*n))
println("qsort using java int[] array")
println(s"before: ${numbers.toList}")
libc.qsort(numbers, numbers.length, 4, new Qsort.IntCompare)
assert(numbers.sorted sameElements numbers)
println(s"after: ${numbers.toList}\n")
println("sort using native memory")
val memory = Memory.allocate(Runtime.getRuntime(libc), 8)
memory.putInt(0, 4)
memory.putInt(4, 3) // offset is in bytes
println("before, memory[0]=" + memory.getInt(0) + " memory[1]=" + memory.getInt(4))
libc.qsort(memory, 2, 4, new Qsort.IntCompare)
println("after, memory[0]=" + memory.getInt(0) + " memory[1]=" + memory.getInt(4) + "\n")
println("qsort using NIO buffer")
val intBuffer = ByteBuffer.allocateDirect(8).order(ByteOrder.nativeOrder).asIntBuffer
intBuffer.put(0, 6)
intBuffer.put(1, 5) // offset is in units of int elements
println("before, buffer[0]=" + intBuffer.get(0) + " buffer[1]=" + intBuffer.get(1))
libc.qsort(intBuffer, 2, 4, new Qsort.IntCompare)
println("after, buffer[0]=" + intBuffer.get(0) + " buffer[1]=" + intBuffer.get(1))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment