Created
December 3, 2017 00:12
-
-
Save kammoh/13b09b6f4b67de610dadc76434622a29 to your computer and use it in GitHub Desktop.
jni-ffi examples in scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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