Я пытаюсь определить вспомогательный метод для динамического создания динамически загружаемых функций.
import scala.scalanative.native._
@extern
@link("dl")
object dl {
def dlopen(path: CString, mode: CInt): Ptr[Byte] = extern
def dlsym(handle: Ptr[Byte], sym: CString): Ptr[Unit] = extern
}
object Sample extends App {
type Lambda = CFunctionPtr1[Ptr[Unit], Ptr[Unit]]
def compose[A,B](fs: Lambda*)(in: Ptr[A]): Ptr[B] =
fs.foldLeft(in.asInstanceOf[Ptr[Unit]]){case (acc, f) =>
f.apply(acc)
}.asInstanceOf[Ptr[B]]
def compose[A, B](f: Lambda, g: Lambda)(in: Ptr[A]): Ptr[B] =
g(f(in.asInstanceOf[Ptr[Unit]])).asInstanceOf[Ptr[B]]
Zone { implicit alloc =>
val handle = dl.dlopen(toCString("functions.so"), 1)
val fOne = dl.dlsym(handle, toCString("one")).asInstanceOf[Lambda]
val fTwo = dl.dlsym(handle, toCString("two")).asInstanceOf[Lambda]
val ptr = stdlib.malloc(sizeof[CInt]).asInstanceOf[Ptr[CInt]]
val result = compose[CInt, CBool](fOne, fTwo)(ptr)
println(!result)
}
}
Приведенный выше код работает с фиксированными аргументами compose
, но не с переменными аргументами compose
.
В последнем случае я получаю:
[error] (Compile / nativeLink) scala.scalanative.util.UnsupportedException: can't cast from Class(Top(java.lang.Object)) to Ptr
Я использую scala native 0.3.9
со scala 2.11.12
.