2009年6月30日 星期二

神出鬼沒

最近的我,神出鬼沒。

有人叫我要寫些生活瑣事在blog上,我本來是打算只紀錄長篇文章的,一些垃圾話寫在醉資心就好,不過 BBS 也不是大家都會看。

最近的我,在忙著失眠。躺在床上時很多正事雜事感情事都衝進我腦海裡,我不知道要拿哪件事當作作夢的題材。

我懷疑,跟我最近每天晚上喝檸檬紅茶有關,畢竟我平時不喝茶的。

出國的準備停滯中,不管拿什麼照片去都被打槍是怎樣 =_=,上次是耳朵沒完全露出來,這次是頭太小,明天打電話請相館再重新洗一份。

簽證、補助、旅館、行程,卡卡的。

重點來了,未來一週要準備雲端的比賽,我也還想找時間自己導一次 MDCT 公式,也要推進一下研究進度。

腦袋打結,好像該重開機了,別再讓scheduling錯亂掉,而且,睡眠不足是很容易感冒的。

2009年6月25日 星期四

[java] Java Native Interface(JNI) 簡介與教學

睡前來統整一下以前找過跟做過的資料,方便給隊友們參考,當然有其他不足或錯誤的地方也請大家指正。我主要是針對幾個常用的case來介紹,並不打算深入探討細節的部份。

JNI 是用來讓Java跟別種語言溝通的函式庫,如果我們舉C/C++ 為例,便分為C call JavaJava call C

Java call C

這段是參考[1]的第二章。

1. 建立一個 Java class (HelloWord.java)。在這個class裡宣告一個native method (print),然後在 main() 裡呼叫這個 method。此時,我們呼叫 printf() 時,它的實體是用 C/C++ 所寫的。

 class HelloWorld {
    private native void print();
    public static void main(String[] args) {
        new HelloWorld().print();
    }
    static {
        System.loadLibrary("HelloWorld");
    }
}

上例中的System.loadLibrary("HelloWorld")會去找你程式目錄下的HelloWorld.dllHelloWorld.so,這之後會提到。

2. Compile HelloWorld.java,用javac指令。

3. 產生一個 native method 的 header file。

指令: javah -jni HelloWorld

這裡,我們用javah可以產生 .h 檔,接著就是實作這個 .h 檔的 .cpp,然後就可以 compile 成 .dll 或 .so 了。cpp 的範例如下:

 #include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"

JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
    printf("Hello World!\n");
    return;
}

記得專案的設定中需指定好 jni.h 的目錄。如果是用VS系列的話,專案新增時選DLL版本,compile過後就會輸出HelloWorld.dll。

4. 最後,將HelloWorld.class跟HelloWorld.dll放在一起後,執行 java HelloWorld 就可以看到結果囉。

註: HelloWorld.dll 其實也不一定要跟 HelloWorld.class 放在一起,有個環境變數叫LD_LIBRARY_PATH,它便是用來設定 native library path。還有一種方式,就是利用java指令來指定路徑。下方是將路徑設為當前目錄。

java -Djava.library.path=. HelloWorld

C call Java

這段是參考[1]的第七章與其他收集的資料。

首先,我們用java寫一個 class Prog,請他印出些字,然後用javac去compile出 .class。

 public class Prog {
    public static void main(String[] args) {
         System.out.println("Hello World " + args[0]);
    }
}

基本上這段程式是可以直接用java指令去執行的,但我們的目標是要產生一個 .c 檔來呼叫它,其流程大致如下:

  1. 喚醒 Java VM
  2. 載入指定class path下的所有 .class 們
  3. 找到你想要執行的class及其 method ID。
  4. 呼叫 method。

對照第七章的範例來看的話,步驟一加二的程式如下。舊版的JNI 有提供JNI_GetDefaultJavaVMInitArgs,新版的還是請大家自己乖乖指定好 class path 跟其他資訊。JNI_CreateJavaVM 會提供兩個重要的指標,jvm 是指向一個新開的JavaVM,env則是待會讓你用來對java class做怪怪事的介面。

     JavaVMInitArgs vm_args;
    JavaVMOption options[1];
    options[0].optionString =
        "-Djava.class.path=" USER_CLASSPATH;
    vm_args.version = 0x00010002;
    vm_args.options = options;
    vm_args.nOptions = 1;
    vm_args.ignoreUnrecognized = JNI_TRUE;
    /* Create the Java VM */
    res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

步驟三加四如下。

     cls = (*env)->FindClass(env, "Prog");
    if (cls == NULL) {
        goto destroy;
    }

    mid = (*env)->GetStaticMethodID(env, cls, "main",
                                    "([Ljava/lang/String;)V");
    if (mid == NULL) {
        goto destroy;
    }
    jstr = (*env)->NewStringUTF(env, " from C!");
    if (jstr == NULL) {
        goto destroy;
    }
    stringClass = (*env)->FindClass(env, "java/lang/String");
    args = (*env)->NewObjectArray(env, 1, stringClass, jstr);
    if (args == NULL) {
        goto destroy;
    }
    (*env)->CallStaticVoidMethod(env, cls, mid, args);

比較可能看不懂的地方是在GetStaticMethodID的第四個參數,這種詭異的寫法稱為JNI signature,當我們呼叫 Java method 時需要寫一些 signature,用來檢查你指定的型態是否與該 method 一樣。舉些例子好了。

Java constructor:

String s

對應到的signature為:

(Ljava/lang/String;)V

Java method:

String toString()

對應到的signature為:

()Ljava/lang/String;

Java method:

long myMethod(int n, String s, int[] arr)

對應到的signature為:

(ILjava/lang/String;[I)J

看了那麼多一定還看不懂對吧?基本上,一個函式會有參數值與回傳值,signature 的規則便是先用 () 描述參數值型態,後面再接回傳值型態。比較特別的,是如果有用到某個 package,除了要打出 package path 外還要加個分號!

下面列出其對應的所有規則,比較一下就可以知道了。

  • B=byte
  • C=char
  • D=double
  • F=float
  • I=int
  • J=long
  • S=short
  • V=void
  • Z=boolean
  • Lfully-qualified-class=fully qualified class
  • [type=array of type>
  • (argument types)return type=method type. If no arguments, use empty argument types: (). If return type is void (or constructor) use (argument types)V.

如果 method signature 不對的話,還會出現類似以下的錯誤訊息。

#
# An unexpected error has been detected by Java Runtime Environment:
#
#  Internal Error (sharedRuntime.cpp:552), pid=7304, tid=2492
#  Error: guarantee(cb != 0,"exception happened outside interpreter, nmethods and vtable stubs (1)")
#
# Java VM: Java HotSpot(TM) Client VM (10.0-b19 mixed mode, sharing windows-x86)
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

最後,你可能會想問:我要如何知道一個 Java class 裡的所有 method 到底需要哪幾種 signature ? 除了自己一個個看以外,J2SDK 有提供神奇指令來幫助我們!

javap -s -p classname

Reference:

[1] Java Native Interface: Programmer's Guide and Specification

[2] Invocation API of JNI Enhancement

[3] Creating a JVM from a C Program

[4] JNI Spec

[5] JNI Functions

2009年6月20日 星期六

生まれゆくものたちへ(D.A.I)

很難得我會連續介紹同一支樂團,不過他們在6/17出單曲了,這是主打歌,聽起來跟過去的fu不太一樣噢。



剛回家聽了一下 (Lab的PC開youtube竟然會lag了,cpu 100%,該死的DPCs),覺得這首歌好聽是好聽,但實在是滿普通的,也沒有以前D.A.I.的感覺。嘗試改變是好事,希望他們別失去自己原有的特色。

最近比較忙,沒空整理資料貼長一點的文章了 @_@,連這一季的日劇都完全還沒開始看。(泣)

2009年6月10日 星期三

Love Shuffle

雖然時間很晚了,但我知道我再不貼心得,這部日劇就要石沉大海了。雖然是半年前的日劇,但在某個週六我無聊開了第一集來看時,就一路將10集看完,約花八個小時。當下看完的感覺是:有種談了好幾次戀愛的感覺

本篇內容依舊是有雷,慎入!

Love Shuffle 這部戲是由四男四人為主體所構成,一開始在電梯裡的邂逅是由宇佐美啟、逢沢愛瑠、世良旺次郎、菊田正人這三男一人開始的,之後再帶出另外四個人,最後一起加入了交換戀人的牌局中。

在電梯中,三個男生在唱著Dancing Queen,愛瑠真的要蹲下去小解了。XD

擷取

這四對的關係十分有趣。小兔跟芽衣是交往很久、論及婚嫁的戀人,芽衣卻中途提出解除婚姻的想法,因為她是千金小姐,自從小兔因她的關係進了爸爸的公司當主管後,小兔就失去了閃閃發亮的氣息,反正就是個吃軟飯的;愛瑠跟諭吉還滿特別的,因為諭吉感覺就是現代宅宅+恐怖份子,外表傻傻的骨子裡只聽自己認同的人的話,而且容易給人壓力,愛瑠則是因為同情他而跟他在一起,卻發現這股壓力讓她不適應,畢竟愛瑠是個很獨立的人;旺次郎跟鈴子是炮友,一個厲害的攝影師跟人妻沒什麼好討論感情面的,不過鈴子的角色本來就是想營造一個純肉體主義的形象,「小孩子還是要生得漂亮」這理由都出現了;最後一對則是醫生與病人的關係,菊田是精神科醫師,海里則是個想在20歲生日後自殺的少女。

第一輪的愛殺,最搶戲的大概是鈴子吧 XDD,她最後還是把小兔給吃了 (吼~)。旺次郎跟愛瑠只有擦出一點小火花,不過我覺得剛開始最有趣的是菊田跟旺次郎,因為他們兩個都會去探究出人心深處的感情面。當然,值得探究的也只有愛瑠跟芽衣,鈴子是為了生小孩才來的,海里嘛。。。實在是有點太單純了,受死神所趨使的意志因為愛跟嫉妒,進一步轉為生存意志,這種設定有點太簡單了,但我還是有哭哦!在海里後來出現在旺次郎面前時。

擷取 

擷取2

這部我的哭點有很多,尤其後面菊田隱瞞海里活著又扮黑臉這件事,我完完全全被前面的設定跟演技給騙了!愛瑠那一巴掌看起來真的超痛的啊。其實不只後面幾集的重點都擺在海里跟旺次郎,整個愛殺遊戲本來就是為海里所設計,只是同時也幫助別人找到真愛,也幫了鈴子生了可寶寶。

到底誰才是真愛?通常一個人要在情海中打滾一陣子,嘗盡各種苦頭(or甜頭?)後才會了解自己想要的是什麼,但這部戲卻簡單的設計了幾個愛情模型,透過兩輪的愛殺洗牌說明,其實無論是個性、背景、還是價值觀,相處時的契合度,加上閃閃發亮的氣質,似乎才是大家所尋找的重點。海里對旺次郎而言是很特別的存在,擅於挖出別人心聲的人竟然遇到一個完全沒有感情的精神病患,甚至對藝術的創作還遠勝過自己,旺次郎很自然的就被她吸引過去。為什麼愛瑠不行?因為對旺次郎來說,愛瑠跟一般女人無異。至於愛瑠跟小兔則是標準的「朋友變情侶」模型,我個人也是滿喜歡這種類型的啦 (科科),因為相處很輕鬆,平時可以打鬧,重點是兩個人都知道彼此的缺點,即使會為這些事吵架也沒關係,至少可以互相鼓勵跟扶持,而不是只有單方面的拉著另一個跑 (像小兔跟芽衣)。菊田跟鈴子這配對實在是有點冷靜。諭吉跟芽衣在個性上是真的滿適合的,芽衣是那種很貼心也很乖的女生,跟小兔這種萬人迷配是真的滿累的,反正像諭吉這種超級死忠的人適合她,只是結局這種玩法也實在有點誇張,竟然因為一句「如果你脫了衣服,我會請你穿上以免感冒」芽衣就軟化了。。。

擷取3

擷取4

如果是我,我覺得我說:「沒關係,我也把衣服脫掉來幫你取暖就好了。」的機會還滿大的。

話說,我看了一下吉高的資料,她竟然有客串過時效警察,其他的戲我就沒聽說了;谷原大叔真的很愛接戲來演,如果出演的list像paper list那樣的話他現在應該是「日劇Fellow」了吧?松田演的戲沒有我想像中那麼多耶,不過都還是滿重要的角色的,新一季的名偵探守則有空再來看看。

最後還是要來句:

Yeah! Panda!

嘘だと言ってよ、ジョー!

2009年6月9日 星期二

本日ハ晴天ナリ (D.A.I.)

大無限樂團 (Do As Infinity) 的歌曲總是給人活力與歡樂的感覺,或許聽久了會膩,不過偶爾拿出來重聽一下感覺還不錯。夏天到了,近期推薦歌曲就放這首"本日ハ晴天ナリ"吧,雖然夏天非常悶熱心情會很煩躁,不過希望這首歌能帶給大家更多活力及勇氣,否則就如歌詞所說:「美好的夏天就要溜走了唷」。

最後,獻上一張歷史課本上出現過的圖。

image  衝啊啊啊~~~

補充: 2008年D.A.I.神秘復出時的影片。