Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala c integration

Tags:

c

scala

sbt

I would like to port some of my scala code to c and call this ported code from my current project. But I did not find any documentation about how to do that. It would be great if this would be possible just from sbt, because thats my current build system.

Currently I have heared about SNA, but without documentation

I am not looking for an automatic scala to c compiler or anything like that. I just don't know how to write the interface between scala and c

like image 454
Arne Avatar asked Jun 08 '11 22:06

Arne


2 Answers

I doubt that you will find a sbt-only solution for compiling C code. Even if you found an sbt plugin that did compile C code, I would be really surprised if it did it well. Compiling native libraries is just too different compared to compiling Scala.

For compiling your C or C++ library, I recommend CMake or Automake. Neither is perfect, but both do a good job of allowing you to basically declare "compile these .c or .cpp files into a .so". Automake is more popular with open source projects, but CMake is quite a bit simpler. CMake also has good support for compiling on Windows, if that's a requirement.

For accessing your native library from Scala, I recommend using JNA. It allows you to access native code from any JVM language, including Scala. And it does so without the glue layer or code generation required by JNI.

I've ported the JNA example from Java to Scala. There are a couple of things to note.

  1. Java varargs are different from Scala varargs. If you want to call a variadic C function, you'll have to write the interface in Java instead of Scala. But you will use that interface exactly like you would if it were written in Scala.
    • I wanted the example to remain strictly in Scala, so I used puts instead of printf in the example
  2. I did pretty much a straight port. You may want to make things a bit for Scala-esque.

And the code:

import com.sun.jna.{Library, Native, Platform}

trait CLibrary extends Library {
  def puts(s: String)
}

object CLibrary {
  def Instance = Native.loadLibrary(
    if (Platform.isWindows) "msvcrt" else "c",
    classOf[CLibrary]).asInstanceOf[CLibrary]
}

object HelloWorld {
  def main(args: Array[String]) {
    CLibrary.Instance.puts("Hello, World");
    for ((arg, i) <- args.zipWithIndex) {
      CLibrary.Instance.puts(
        "Argument %d: %s".format(i.asInstanceOf[AnyRef], arg))
    }
  }
}

As an aside, it's funny that you mention specifically not wanting a Scala to C compiler. There was a recent paper published about compiling Scala to LLVM, which would have largely the same effect as a Scala to C compiler.

like image 116
leedm777 Avatar answered Nov 05 '22 07:11

leedm777


Scala and C are fundamentally different programming languages. You cannot expect to have an automatic converter from Scala to C.

If you want to call Scala code from C code or vice-versa, you should use the Java Native Interface (JNI). In this case, you will have a running JVM executing your Scala code, and that JVM will load your C code as a dynamic native library and allow it to interact with your Java/Scala code through JNI. It's not easy or straightforward though; you have to read and try out a lot.

like image 13
Madoc Avatar answered Nov 05 '22 07:11

Madoc