Enums 维护本机C++;enum和Java enum同步 我有一个要求,其中我在原生C++代码中有一个枚举,作为[所有伪代码]: enum Dummy { A, B, MAX, };

Enums 维护本机C++;enum和Java enum同步 我有一个要求,其中我在原生C++代码中有一个枚举,作为[所有伪代码]: enum Dummy { A, B, MAX, };,enums,java-native-interface,Enums,Java Native Interface,现在我还希望在Java代码中有一个等价的枚举 public static enum Dummy { A, B, MAX }; 双重定义会使事情变得非常脆弱和容易出错,开发人员会有一阵阵的健忘症或怠惰。是否有一些具体的方法使它们始终保持同步。我不想要一堆问题所建议的#定义。去一个艰难的预处理器,方法;) 我们可以在Java中使用枚举 /* B.java */ public class B { public static void main(String [] arg) { A

现在我还希望在Java代码中有一个等价的枚举

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

双重定义会使事情变得非常脆弱和容易出错,开发人员会有一阵阵的健忘症或怠惰。是否有一些具体的方法使它们始终保持同步。我不想要一堆问题所建议的
#定义

去一个艰难的预处理器,方法;)

我们可以在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

您可以使用构造函数创建
enum
,以便为其分配所需的值,然后使用JNI调用获取该enum的值。Java中的类似代码(请注意,我根本没有测试过这段代码,但我在过去编写过类似的代码,以完全满足您的需要):

在本地方面:

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 );
}
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 );
}
确保使用
javah
生成本机函数签名,并在代码中包含生成的头

或者,您可以将其他内容传递给本机函数,以标识要返回的枚举值,例如映射到实际枚举值的字符串:

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 );
    }

    ...
}
在本土方面:

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 );
}
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 );
}

您仍然需要处理一些O&M开销,但这样实际值只在一个地方定义。在这种情况下,它是在本机代码中。

继续……你是不是要我用C++代码中包含一个java文件?cc扩展是否允许这样做?和<代码> >定义公共< /代码>,是否给出了公共代码是C++中的关键字的法律代码?谢谢您的全面回答,但我不能确定这是否是来自开发人员意外错过的证据。就像他在本机代码中添加一个枚举值
x
,但在java代码中忘记询问相应的
x(getX())
。不过,您的回答确实解决了多重定义部分。我是不是遗漏了什么?
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 );
}