1

I am trying to define a helper method to dynamically compose functions which are dynamically loaded.

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)
  }
}

The above code works with the fixed args compose but not with the varargs compose.

In the latter case I am getting:

[error] (Compile / nativeLink) scala.scalanative.util.UnsupportedException: can't cast from Class(Top(java.lang.Object)) to Ptr

I am using scala native 0.3.9 with scala 2.11.12.

GuoLiang Oon
  • 163
  • 6

1 Answers1

0

The above error has been fixed in 0.4.0 but another issue for CFuncPtr <-> Ptr[Byte] conversion remains in scala native.

GuoLiang Oon
  • 163
  • 6