Skip to content

Instantly share code, notes, and snippets.

@kijuky
Last active March 13, 2016 15:30
Show Gist options
  • Save kijuky/485837248a86a75b7035 to your computer and use it in GitHub Desktop.
Save kijuky/485837248a86a75b7035 to your computer and use it in GitHub Desktop.
CGIで実行されたScala上で、JNIを通してネイティブコードを実行します。
$ scalac Sample1.scala
$ ./scalah.sh 'Main$$anon$1$Sample1' ← シングルクォーテーションつけないと $ を変数と勘違いする
$ ./nvc.sh hello.c
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
clang: warning: argument unused during compilation: '-G -Wall'
$ ./scala1.cgi
Content-Type: text/html; charset=UTF-8
<html>
NATIVE_OUTPUT:
Hello World!
</html>
#include "Main___anon__1_Sample1.h"
JNIEXPORT void JNICALL Java_Main_00024_00024anon_000241_00024Sample1_hello (JNIEnv *env, jobject obj) {
printf("Hello World!\n");
}
#!/bin/sh
# ネイティブコードからダイナミックライブラリ(dylib)を作成します。
JAVA_HOME=$(/usr/libexec/java_home)
g++ -dynamiclib -G -Wall -O3 \
-I/usr/include -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin \
$1 -o lib${1%.*}.dylib
/** このクラスは、ヘッダを作成するためだけに使います */
class Main { new { // ← CGI ではスクリプト(REPL)として実行されるため、それを模倣
class Sample1 {
@native def hello()
}
}}
#!/bin/sh
exec /usr/local/bin/scala -Djava.library.path=/Users/<<usernam>>/Sites "$0" "$@"
!#
import System._
class Sample1 { // 先に定義したクラス名と同じクラス名にする
@native def hello() // @native でネイティブメソッドを宣言
}
object Sample1 {
def apply() = new Sample1
loadLibrary("hello") // loadLibrary で libhello.dylib を読み込む(lib と .dylib は省略する)
}
println("Content-Type: text/html; charset=UTF-8\r\n\r\n")
println("<html>")
println("NATIVE_OUTPUT:")
Sample1.apply().hello() // ← 一旦 object を経由して static イニシャライザを呼ばせる
println("</html>")
#!/bin/sh
# scala のコードから JNI ヘッダーを作成します。
# ここでは brew で scala をインストールしていることを想定しています。
SCALA_LIB_HOME=/usr/local/Cellar/scala/2.11.8/libexec/lib/
SCALA_CP=$SCALA_LIB_HOME/scala-library.jar:$SCALA_LIB_HOME/scala-reflect.jar
javah -cp $SCALA_CP:. "$1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment