2017-08-01 39 views
2

我有一個要求,其中我在本地C枚舉++代碼爲[所有僞]:維護本地C++枚舉和Java枚舉同步

enum Dummy { 
A, 
B, 
MAX, 
}; 

現在我也希望有在Java代碼的等效枚舉

public static enum Dummy { 
A, 
B, 
MAX 
}; 

雙重定義使得事情變得非常脆弱和容易出錯,受到部分開發人員的失憶症或無聊感。有沒有一些具體的方法來始終讓它們同步。我不想要this問題所建議的一堆#defines

回答

0

去硬,預處理程序,方式;)

/* main.cc */ 
#include <stdio.h> 

#define public 
#include "A.java" 
; 
#undef public 

int main() { 
    A val = a; 
    if(val == a) { 
    printf("OK\n"); 
    } else { 
    printf("Not OK\n"); 
    } 
} 

Java代碼

/* A.java */ 
public 
enum A { 
    a, 
    b 
} 

我們可以用枚舉在Java中

/* B.java */ 
public class B { 
    public static void main(String [] arg) { 
    A val = A.a; 
    if(val == A.a) { 
     System.out.println("OK"); 
    } else { 
     System.out.println("Not OK"); 
    } 
    } 
} 

和執行

> javac *.java 
> java B 
OK 
> g++ -o main ./main.cc 
> ./main 
OK 
+1

堅持...你是問我在C++代碼中包含Java文件嗎? cc擴展是否允許這樣做?並且'#define public',那個公共是C++中的關鍵字的合法代碼? – Zoso

0

你可以用一個構造函數創建你的enum,這樣你就可以爲它分配你想要的值,然後使用一個JNI調用來獲得該枚舉的值。像這樣在Java中的東西(請注意,我沒有測試此代碼在所有,但我已經寫類似的代碼在過去做的正是你所需要的):

public class TestEnum 
{ 
    public enum Dummy 
    { 
     A(getA()); 
     B(getB()); 
     MAX(getMax()); 

     private final int value; 

     Dummy(int newValue) 
     { 
      this.value = newValue; 
     } 

     int getValue() 
     { 
      return(this.value); 
     } 

     private static native int getA(); 
     private static native int getB(); 
     private static native int getMAX(); 
    } 

    ... 
} 

在本機端:

enum Dummy 
{ 
    A = 100; 
    B = 102; 
    MAX = 912343; 
}; 

... 

JNIEXPORT jint JNICALL Java_TestEnum_00024TEST_getA(JNIEnv *env, jclass cls) 
{ 
    return(A); 
} 
JNIEXPORT jint JNICALL Java_TestEnum_00024TEST_getB(JNIEnv *env, jclass cls) 
{ 
    return(B); 
} 
JNIEXPORT jint JNICALL Java_TestEnum_00024TEST_getMAX(JNIEnv *env, jclass cls) 
{ 
    return(MAX); 
} 

請確保您使用javah來生成您的本機功能簽名,並在您的代碼中生成標頭#include

或者,您也可以通過別的東西來的本地函數來確定枚舉值返回,如映射到實際枚舉值的字符串:

public class TestEnum 
{ 
    public enum Dummy 
    { 
     A(get("A")); 
     B(get("B")); 
     MAX(get("MAX")); 

     private final int value; 

     Dummy(int newValue) 
     { 
      this.value = newValue; 
     } 

     int getValue() 
     { 
      return(this.value); 
     } 

     private static native int get(String enumName); 
    } 

    ... 
} 

,並在本機端:

JNIEXPORT jint JNICALL Java_TestEnum_00024TEST_get(JNIEnv *env, jclass cls, jstring enumName) 
{ 
    char *cEnumName = (*env)->getStringUTFChars(env, enumName, NULL); 
    jint retVal = -1; 
    if (0 == strcmp(cEnumName, "A")) 
    { 
     retVal = A; 
    } 
    else if (0 == strcmp(cEnumName, "B")) 
    { 
     retVal = B; 
    } 
    else if (0 == strcmp(cEnumName, "MAX")) 
    { 
     retVal = MAX; 
    } 

    (*env)->ReleaseStringChars(env, cEnumName); 

    return(retVal); 
} 

您仍然需要處理一些開銷,但這種方式實際值只能在一個地方定義。在這種情況下,它在本機代碼中。

+1

感謝您的全面回答,但我不確定這是否能夠防止開發人員意外遺漏。如果他在本機代碼中添加枚舉值'x',但忘記在java代碼中詢問相應的'X(getX())'。雖然你的答案確實解決了多重定義部分。我在這裏錯過了什麼嗎? – Zoso