在有了這兩個頭文件之后,就可以進行C程序的編寫了。也就是實現(xiàn)對JNI調用的兩個方法。在網上的資料中,由于調用的方法實現(xiàn)的都比較簡單,(大多是打印字符串等)所以避開了JNI中最麻煩的部分,也是最關鍵的部分,參數(shù)的傳遞。由于Java和C的編碼是不同的,所以傳遞的參數(shù)是要進行再處理,否則C程序是會對參數(shù)在編譯過程中提出警告,例如;warning C4024: ‘SmsSend‘ : different types for formal and actual parameter 2等。 Sms.c的程序如下:
#include "sms.h" #include "com_mobilesoft_sms_mobilesoftinfo_SendSMS.h" JNIEXPORT jint JNICALL Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsInit(JNIEnv * env, jclass jobject) { return SmsInit(); }
JNIEXPORT jint JNICALL Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsSend(JNIEnv * env, jclass jobject, jbyteArray mobileno, jbyteArray smscontent) { char * pSmscontent ; //jsize theArrayLengthJ = (*env)->GetArrayLength(env,mobileno); jbyte * arrayBody = (*env)->GetByteArrayElements(env,mobileno,0); char * pMobileNo = (char *)arrayBody; printf("[%s]\n ", pMobileNo); //jsize size = (*env)->GetArrayLength(env,smscontent); arrayBody = (*env)->GetByteArrayElements(env,smscontent,0); pSmscontent = (char *)arrayBody; printf("<%s>\n", pSmscontent); return SmsSend(pMobileNo,pSmscontent); }
對于C或C++,在程序上是會有稍微的不同,這可以由讀者對其進行適當?shù)男薷?。這里要注意的是GetArrayLength,GetByteArrayElements等這些JNI中已經包含的方法,這些方法是專門對轉換參數(shù)類型而提供的。具體的方法有很多,在下一篇中會做專門的介紹。 在完成了上述的文件后,可以對sms.c進行編譯,生成.dll文件(建議在release中編譯,這樣動態(tài)鏈接庫的容積會比較?。。?br> 完成.dll文件的編譯后,就可以在Java中調用C程序中的方法了。例如文件test.java
public class test { public test() { } public static void main(String[] args) { byte[] mobileno = { 0x31, 0x33, 0x36, 0x36, 0x31, 0x36, 0x33, 0x30, 0x36, 0x36, 0x37, 0x00}; String smscontentemp = "早上好"; byte[] temp = {0}; try { byte[] smscontentdb = smscontentemp.getBytes("gbk"); byte[] smscontent = new byte[smscontentdb.length + temp.length]; System.arraycopy(smscontentdb, 0, smscontent, 0, smscontentdb.length); System.arraycopy(temp, 0, smscontent, smscontentdb.length, temp.length); SendSMS sendSMS = new SendSMS(); sendSMS.SmsInit(); if (sendSMS.SmsSend(mobileno, smscontent) >= 0) { System.out.println("chenggong !"); } else { System.out.println("shibai !"); } }catch (Exception ex) {} } }
在這個文件中要注意的有一點,就是在傳遞字節(jié)數(shù)組到C程序中時,最后的結尾一定要以0結束。這是一個偷懶的做法,不過是個有效的做法。因為大多數(shù)情況下,接口是由第三方提供的。所以我們一般是不知道在C的方法里,具體是怎么處理參數(shù)的。而C又是要求數(shù)組是有長度。所以,在Java中,如果你不想寫程序傳數(shù)組的長度,那么在數(shù)組中以0結尾就是最方便的方法了。當然,如果有更好的方法也希望大家提出。
到這里,一個完整的Java通過JNI調用動態(tài)鏈接庫的程序就完成了。實際上也不是很復雜。只要多注意一下細節(jié),是很容易得出來的。
|