2016-04-16 69 views
0

我有要求整合春天與一些本地代碼編寫C和我是新的春天,並沒有任何關於它有任何想法,如果任何人有經驗整合春天與JNI然後請與我分享。如何用jni配置spring?

在此先感謝。

回答

1

這個問題很模糊,但我可以提供一些我過去所做的工作建議。

  1. 忘記整合「春天」。集中精力與Java集成,讓Spring稍後幫助你。
  2. 要非常非常小心地處理C中的類型和內存分配。當我在編寫JNI時,我發現它非常有幫助。這有點過時了,但仍然有效
  3. 我在C中完成了大部分工作,然後通過一個簡單的Java方法掛鉤進行修補。這樣我就完成了大部分與本地語言現有代碼的集成。
  4. 爲您的C代碼提供一種主要方法,讓您可以獨立於Java測試C代碼。然後,您可以將C文件編譯爲庫(dll/so)和可執行文件。可執行文件可以通過參數自己調用以測試對現有調用的調用。

一般過程是。

爪哇結束

public class statusBlock { 
    /* A Java representation of a Status Block */ 
    private long errcode = 0; 
    private long errref = 0; 
    private String errmsg = ""; 
    private long[] TmidArray; 
    private long evt_id = 0; 
    private short IgViolation_severity = 0; 
} 

public class MyFunkyJNIClass { 
    private Object response; 

    /** 
    * To generate the C-header for a native call use: javah -jni 
    * example.package.MyFunkyJNIClass from target/classes folder. 
    */ 
    private native int nativeExecuteFunction(int callType, Object payload, Object response); 

    public MyFunkyJNIClass() { 
     System.loadLibrary("theCLibrary"); 
    } 
} 

在上述予加載中用System.loadLibrary代碼的C側和定義一些字段,我可以從我的C代碼填充的例子。要執行只需調用原生函數nativeExecuteFunction(1, "my payload", respObject);在C端,我可以使用第一個參數來選擇要執行的操作。 它簡化了我的問題的時候

C面

JNIEXPORT jint JNICALL Java_example_package_MyFunkyJNIClass_nativeExecuteFunction(JNIEnv *env, jobject this, jint CallType, jobject Payload) 
{ 
    // **** JNI Specific declarations for mapping **** 
    jclass   cls, cls2, cls3; 
    jmethodID  mid, mid2; 
    jfieldID  fid; 
    jint   rc = 0; 
    jsize   js = 0; 
    jbyte   jb; 
    jobject   jobj, jobj2, jro; 
    jobjectArray jobjArray, jobjArray2; 

    _svc_results results; 

    switch ((int)CallType) 
    { 
    case CALLTYPE1:  // 1 
     DEBUG_PRINT("JNI Call Type 1 in progress...\n"); 
     // JNI mapping happens here 
     stat = DoSomethingInC(args, &results); 

     // Map from C structure (_statblk) to Java object 
     if (stat == SUCCESS) { 
      DEBUG_PRINT("\tMapping from C structure (_statblk) to Java object\n"); 

      cls = (*env)->FindClass(env, "Lexample/package/statusBlock;"); 
      mid = (*env)->GetMethodID(env, cls, "<init>", "()V"); if (mid == NULL) return -1; 
      jro = (*env)->NewObject(env, cls, mid); if (jro == NULL) return -1; 

      fid = (*env)->GetFieldID(env, cls, "errcode","I"); if (fid == NULL) return -1; 
      (*env)->SetIntField(env, jro, fid, (jint)results.statblk.errcode); 
      DEBUG_PRINT("\t\tMapped errcode: %d\n",results.statblk.errcode); 

      fid = (*env)->GetFieldID(env, cls, "errref","I"); if (fid == NULL) return -1; 
      (*env)->SetIntField(env, jro, fid, (jint)results.statblk.errref); 
      DEBUG_PRINT("\t\tMapped errref: %d\n",results.statblk.errref); 

      fid = (*env)->GetFieldID(env, cls, "errmsg","[B"); if (fid == NULL) return -1; 
      jobj = (*env)->NewByteArray(env, MAX_ERR); 
      (*env)->SetByteArrayRegion(env, (jbyteArray)jobj, 0, MAX_ERR, (jbyte*)results.statblk.errmsg); 
      (*env)->SetObjectField(env, jro, fid, jobj); 
      (*env)->DeleteLocalRef(env, jobj); 
      DEBUG_PRINT("\t\tMapped errmsg: %s\n",results.statblk.errmsg); 

      fid = (*env)->GetFieldID(env, cls, "TmidArray","[I"); if (fid == NULL) return -1; 
      jobj = (*env)->NewIntArray(env, (jsize)results.statblk.TmidArray.TmidArray_len); 
      (*env)->SetIntArrayRegion(env, (jintArray)jobj, 0, 
             (jsize)results.statblk.TmidArray.TmidArray_len, 
             (jint*)results.statblk.TmidArray.TmidArray_val); 
      (*env)->SetObjectField(env, jro, fid, jobj); 
      (*env)->DeleteLocalRef(env, jobj); 
      DEBUG_PRINT("\t\tMapped TmidArray\n"); 

      fid = (*env)->GetFieldID(env, cls, "evt_id","I"); if (fid == NULL) return -1; 
      (*env)->SetIntField(env, jro, fid, (jint)results.statblk.evt_id); 
      DEBUG_PRINT("\t\tMapped evt_id: %d\n",results.statblk.evt_id); 

      cls = (*env)->GetObjectClass(env, this); 
      fid = (*env)->GetFieldID(env, cls, "response","Ljava/lang/Object;"); if (fid == NULL) return -1; 
      (*env)->SetObjectField(env, this, fid, jro); 

      DEBUG_PRINT("\tMapping from C structure (_statblk) to Java object - DONE\n"); 
     } else { 
      DEBUG_PRINT("JNI Call Type 1 in progress... Returning Error: %d\n", stat); 
      return (jint)stat; 
     } 

     /* Free our native memory */ 
     cls = (*env)->GetObjectClass(env, Payload); 
     fid = (*env)->GetFieldID(env, cls, "message","Ljava/lang/String;"); if (fid == NULL) return -1; 
     jobj = (*env)->GetObjectField(env, Payload, fid); 
     GPS_Free(results.statblk.TmidArray.TmidArray_val); 
     GPS_Free(results.statblk.ErrorArray.ErrorArray_val); 
     DEBUG_PRINT("JNI RTP Posting in progress... DONE\n"); 
     break; 
    case PING:   // 2 
     DEBUG_PRINT("No Java to C mapping required\n"); 
     DEBUG_PRINT("JNI Ping in progress...\n"); 
     stat = doPing(); 

     DEBUG_PRINT("No C to Java mapping required\n"); 
     // Stop null pointer exception if client tries to access the response object. 
     cls = (*env)->FindClass(env, "Lexample/package/EmptySerializableClass;"); 
     mid = (*env)->GetMethodID(env, cls, "<init>", "()V"); if (mid == NULL) return -1; 
     jro = (*env)->NewObject(env, cls, mid); if (jro == NULL) return -1; 

     cls = (*env)->GetObjectClass(env, this); 
     fid = (*env)->GetFieldID(env, cls, "response","Ljava/lang/Object;"); if (fid == NULL) return -1; 
     (*env)->SetObjectField(env, this, fid, jro); 
     DEBUG_PRINT("JNI Ping in progress... DONE\n"); 

     return (jint)rpc_stat; 
     break; 
    default: 
     fprintf(stderr,"Unknown call type\n"); 
     rc = -1; 
     break; 
    } 

    return rc; 
} 

我可以繼續下去,但它只是需要多一點的那本書仔細閱讀。

這並不需要與Spring進一步整合。您可以在MyFunkyJNIClass上粘貼@Component@Service註釋。

我希望這對你有一些幫助。

+0

非常感謝!你提供的信息對我來說真的很有用,直到現在我在霧中漫遊,但現在我可以從透明玻璃看到東西。 –

相關問題