Re: [javacpp-project] C++ enum

313 views
Skip to first unread message

Samuel Audet

unread,
Aug 8, 2012, 9:24:41 PM8/8/12
to javacpp...@googlegroups.com
On 08/09/2012 06:41 AM, Anton wrote:
> Hi all!
>
> For example I have enum TestEnum in C++ and method:
> SomeClass::someMethod(TestEnum e);
>
> How can I use it from Java?

C enum values are just ints, so something like
SomeClass::someMethod(@Cast("TestEnum") int e)
is the easiest way to do it...

Samuel

Anton

unread,
Aug 9, 2012, 2:56:40 AM8/9/12
to javacpp...@googlegroups.com
Thank you, Samuel!
It works, but not meanful and safe :)

IMO it's better to have on Java side:
void someMethod(TestEnum e);

I have done it following way:

public static enum TestEnum {
        ZERO(0),
        ONE(1);

        public int value;

        TestEnum(int level) {
            value = level;
        }

        public static TestEnum fromInt(int v) {
            return values()[v];
        }
}

public static class SomeClass extends Pointer {
        ...
        public void someMethod(TestEnum e) {
            someMethod(e.value);
        }

        private native void someMethod(@Cast("TestEnum") int e);

        private native int enumMethod();
}

1. How to do it more simple and gracefully?
2. What about enumMethod()? How can I translate return value to TestEnum (using TestEnum.fromInt()) and leave the same method name? Of course I can define new wrapper enumMethod2(), but I want to rename private native method instead. How to do it?

четверг, 9 августа 2012 г., 3:24:41 UTC+2 пользователь Samuel Audet написал:

Samuel Audet

unread,
Aug 9, 2012, 3:07:50 AM8/9/12
to javacpp...@googlegroups.com
On 08/09/2012 03:56 PM, Anton wrote:
> Thank you, Samuel!
> It works, but not meanful and safe :)
>
> IMO it's better to have on Java side:
> void someMethod(TestEnum e);
>
> I have done it following way:
>
> public static enum TestEnum {
> ZERO(0),
> ONE(1);
>
> public int value;
>
> TestEnum(int level) {
> value = level;
> }
>
> public static TestEnum fromInt(int v) {
> return values()[v];
> }
> }
>
> public static class SomeClass extends Pointer {
> ...
> public void someMethod(TestEnum e) {
> someMethod(e.value);
> }
>
> private native void someMethod(@Cast("TestEnum") int e);
>
> private native int enumMethod();
> }
>
> 1. How to do it more simple and gracefully?

I don't know. Your code won't work if your enum values are not 0, 1, 2,
... Let me know if you figure out an efficient way, thanks

> 2. What about enumMethod()? How can I translate return value to TestEnum
> (using TestEnum.fromInt()) and leave the same method name? Of course I
> can define new wrapper enumMethod2(), but I want to rename private
> native method instead. How to do it?

You can use @Name() as shown in the README.txt file to specify the
native function name, instead of having JavaCPP pick up the method name
in Java

Samuel

Anton

unread,
Aug 9, 2012, 3:19:19 AM8/9/12
to javacpp...@googlegroups.com
четверг, 9 августа 2012 г., 9:07:50 UTC+2 пользователь Samuel Audet написал:
I don't know. Your code won't work if your enum values are not 0, 1, 2,
... Let me know if you figure out an efficient way, thanks

Yes, in this case I have to use switch in fromInt().

You can use @Name() as shown in the README.txt file to specify the
native function name, instead of having JavaCPP pick up the method name
in Java

Thanks, I will try.

Thanh Liem Phan

unread,
Aug 13, 2015, 6:23:27 AM8/13/15
to javacpp
Hi Anton,

Could you please repost your final working solution here, please?

Thanks for your help.
Thanh Liem.

Anton Babushkin

unread,
Aug 13, 2015, 6:48:47 AM8/13/15
to javacpp...@googlegroups.com
Hi! I've just used method suggested by Samuel:

>SomeClass::someMethod(@Cast("TestEnum") int e)

Also I've added java enum and do casting to/from it. But on JNI level it's still int.

--
Best regards,
Anton Babushkin



13 авг. 2015 г., в 11:35, Thanh Liem Phan <thanhlie...@gmail.com> написал:

--
You received this message because you are subscribed to a topic in the Google Groups "javacpp" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/javacpp-project/mSGTOFweVQU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to javacpp-proje...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Thanh Liem Phan

unread,
Aug 13, 2015, 9:34:28 AM8/13/15
to javacpp
Hi Anton,

I have the following structs:

struct Struct_Simulation_Results {
    Simulation_Flag         Flag;
    structTimeSeriesResults s_timeSeriesResults;
    Vector_Double           vd_Indicators;
};

enum Simulation_Flag {
    Simulation_OK = 0,
    Initialisation_Failed = 1,
    Simulation_Failed = 2
};

struct structTimeSeriesResults {...}

Follow your example, this is the corresponding Javacpp code:
@Namespace("")
public static class Struct_Simulation_Results extends Pointer {
static { Loader.load(); }
public Struct_Simulation_Results () { allocate(); }
private native void allocate();
public native Simulation_Flag Flag(); public native Struct_Simulation_Results Flag(Simulation_Flag Flag);
public native structTimeSeriesResults s_timeSeriesResults(); public native Struct_Simulation_Results s_timeSeriesResults(structTimeSeriesResults s_timeSeriesResults);
public native @StdVector DoublePointer vd_Indicators(); public native Struct_Simulation_Results vd_Indicators(@StdVector DoublePointer vd_Indicators);
}

@Namespace("")
public static enum Simulation_Flag {
Simulation_OK(0), Initialisation_Failed(1), Simulation_Failed(2);
private int value;
private Simulation_Flag(int value) {
this.value = value;
}
}

So when i compile, i got the following error:
Warning: The class testspidercpp.Simulation_Flag does not map to any C++ type. Compilation will most likely fail.

It seems that I misses something.
Do you have any idea? 

Thanks you.

Anton Babushkin

unread,
Aug 13, 2015, 10:28:51 AM8/13/15
to javacpp...@googlegroups.com
13 авг. 2015 г., в 15:34, Thanh Liem Phan <thanhlie...@gmail.com> написал:

Hi Anton,

I have the following structs:

struct Struct_Simulation_Results {
    Simulation_Flag         Flag;
    structTimeSeriesResults s_timeSeriesResults;
    Vector_Double           vd_Indicators;
};

enum Simulation_Flag {
    Simulation_OK = 0,
    Initialisation_Failed = 1,
    Simulation_Failed = 2
};

struct structTimeSeriesResults {...}

Follow your example, this is the corresponding Javacpp code:
@Namespace("")
public static class Struct_Simulation_Results extends Pointer {
static { Loader.load(); }
public Struct_Simulation_Results () { allocate(); }
private native void allocate();
public native Simulation_Flag Flag(); public native Struct_Simulation_Results Flag(Simulation_Flag Flag);

No, return type must be int, and argument must have type @Cast("Simulation_Flag") int!

public native structTimeSeriesResults s_timeSeriesResults(); public native Struct_Simulation_Results s_timeSeriesResults(structTimeSeriesResults s_timeSeriesResults);
public native @StdVector DoublePointer vd_Indicators(); public native Struct_Simulation_Results vd_Indicators(@StdVector DoublePointer vd_Indicators);
}

@Namespace("")
public static enum Simulation_Flag {
Simulation_OK(0), Initialisation_Failed(1), Simulation_Failed(2);
private int value;
private Simulation_Flag(int value) {
this.value = value;
}
}

This is also wrong, it should be normal Java enum, without any native-related attributes like @Namespace.
And if you want your getter to return Java enum you should do it by hands, example from my code:

public MessageType getType() {
return MessageType.fromInt(nativeGetType());
}

private native @Name("getType") int nativeGetType();
Here MessageType is normal Java enum.

Hope this helps.

Thanh Liem Phan

unread,
Aug 13, 2015, 10:46:54 AM8/13/15
to javacpp
Hi Anton,
Thanks for your quick reply.

Yes, i've made some errors.
In fact,  @Cast("Simulation_Flag") int! works well.

So this is the modified javacpp code:

public static class Struct_Simulation_Results extends Pointer {
static { Loader.load(); }
public Struct_Simulation_Results () { allocate(); }
private native void allocate();
public native Simulation_Flag Flag(); public native Struct_Simulation_Results Flag(@Cast("Simulation_Flag") int Flag);
public native structTimeSeriesResults s_timeSeriesResults(); public native Struct_Simulation_Results s_timeSeriesResults(structTimeSeriesResults s_timeSeriesResults);
public native @StdVector DoublePointer vd_Indicators(); public native Struct_Simulation_Results vd_Indicators(@StdVector DoublePointer vd_Indicators);
}

public static enum Simulation_Flag {
Simulation_OK(0), Initialisation_Failed(1), Simulation_Failed(2);
private int value;
private Simulation_Flag(int value) {
this.value = value;
}
}


However, i don't really understand how Javacpp can map my java enum Simulation_Flag with my C++ enumeration Simulation_Flag in this case?

And your code concerning the getter:

public MessageType getType() {
return MessageType.fromInt(nativeGetType());
}

private native @Name("getType") int nativeGetType();

Why @Name("getType") here? What does this mean? and  What is the relationship with the C++ header?

Thanks for your help.
Liem.

Anton Babushkin

unread,
Aug 13, 2015, 11:59:45 AM8/13/15
to javacpp...@googlegroups.com
13 авг. 2015 г., в 16:46, Thanh Liem Phan <thanhlie...@gmail.com> написал:

Hi Anton,
Thanks for your quick reply.

Yes, i've made some errors.
In fact,  @Cast("Simulation_Flag") int! works well.

So this is the modified javacpp code:

public static class Struct_Simulation_Results extends Pointer {
static { Loader.load(); }
public Struct_Simulation_Results () { allocate(); }
private native void allocate();
public native Simulation_Flag Flag(); public native Struct_Simulation_Results Flag(@Cast("Simulation_Flag") int Flag);
public native structTimeSeriesResults s_timeSeriesResults(); public native Struct_Simulation_Results s_timeSeriesResults(structTimeSeriesResults s_timeSeriesResults);
public native @StdVector DoublePointer vd_Indicators(); public native Struct_Simulation_Results vd_Indicators(@StdVector DoublePointer vd_Indicators);
}

public static enum Simulation_Flag {
Simulation_OK(0), Initialisation_Failed(1), Simulation_Failed(2);
private int value;
private Simulation_Flag(int value) {
this.value = value;
}
}


However, i don't really understand how Javacpp can map my java enum Simulation_Flag with my C++ enumeration Simulation_Flag in this case?

Nohow, you do it by hands, javacpp always sees only int on java side.

And your code concerning the getter:

public MessageType getType() {
return MessageType.fromInt(nativeGetType());
}

private native @Name("getType") int nativeGetType();

Why @Name("getType") here? What does this mean? and  What is the relationship with the C++ header?

Native getter is getType, but it's mapped to nativeGetType java method to save name "getType" for java wrapper method.
So on user side API looks more beautiful.

Thanh Liem Phan

unread,
Aug 15, 2015, 9:50:12 AM8/15/15
to javacpp
Thanks Anton for your help.
Have a nice weekend.
Best regards.
Thanh Liem.

On Thursday, 9 August 2012 03:24:41 UTC+2, Samuel Audet wrote:

Thanh Liem Phan

unread,
Aug 17, 2015, 8:46:50 AM8/17/15
to javacpp
Hi Anton,

I still have trouble. This is my c++ header:
struct Struct_Simulation_Results {
 
Simulation_Flag Flag;

 
};

enum Simulation_Flag
{
 
Simulation_OK = 0,
 
Initialisation_Failed = 1,
 
Simulation_Failed = 2
};

And here are my Java code for the enum Simulation_Flag:
public static class Struct_Simulation_Results extends Pointer {
 
static { Loader.load(); }
 
 
public Struct_Simulation_Results () { allocate(); }
 
private native void allocate();

 
 
@NoOffset public native Simulation_Flag Flag();

 
public native Struct_Simulation_Results Flag(@Cast("Simulation_Flag") int Flag);
 
}

public static enum Simulation_Flag {
 
Simulation_OK(0), Initialisation_Failed(1), Simulation_Failed(2);
 
private int value;
 
private Simulation_Flag(int value) {
 
this.value = value;
 
}
 
}



But I still have a compilation error:

Line 1480 : rptr = ptr->Flag();
Line 1503 : rptr = ptr->Flag((Simulation_Flag)arg0);
I think lin 1480 should only be,
rptr = ptr->Flag
Shouldn't it?

What's wrong with my code here?
Why in the compiled file.cpp there is a call to Flag() instead of Flag in this case.

Samuel Audet

unread,
Aug 17, 2015, 9:13:52 AM8/17/15
to javacpp...@googlegroups.com
On 08/17/2015 09:46 PM, Thanh Liem Phan wrote:
> What's wrong with my code here?
> Why in the compiled file.cpp there is a call to Flag() instead of Flag in this case.
>

JavaCPP doesn't support Java enum on `native` methods. Use `int` instead.

Samuel

Thanh Liem Phan

unread,
Aug 17, 2015, 9:34:24 AM8/17/15
to javacpp
Hi Samuel,

So in this case, what should be changed to `int`?
I've tried several one, but it seems no effect.
Could you please give me more info?

Thanks.
Thanh Liem.

Samuel Audet

unread,
Aug 17, 2015, 9:40:01 AM8/17/15
to javacpp...@googlegroups.com
On 08/17/2015 10:34 PM, Thanh Liem Phan wrote:
> Hi Samuel,
>
> So in this case, what should be changed to `int`?
> I've tried several one, but it seems no effect.
> Could you please give me more info?

Change this
@NoOffset public native Simulation_Flag Flag();
to this
public native @Cast("Simulation_Flag") int Flag();

Samuel

Thanh Liem Phan

unread,
Aug 17, 2015, 9:44:52 AM8/17/15
to javacpp
Thank you Samuel,

This works well : 
public native @Cast("Simulation_Flag") int Flag(); public native Struct_Simulation_Results Flag(@Cast("Simulation_Flag") int Flag);

Best Regards.

Piotr Chromiec

unread,
Nov 4, 2016, 8:54:55 PM11/4/16
to javacpp
Here's how I managed to couple Java-enum with C-enumeration

Java side:


private static native @MemberGetter @Const int TRANSPOSE();
private static native @ValueGetter @Const int NO_TRANSPOSE();
public enum Trans {
TRANSPOSE(TRANSPOSE()), NO_TRANSPOSE(NO_TRANSPOSE());
private int value;
Trans(int value) {
this.value = value;
}
private int value() {
return value;
}
}

C side:
can you explain what are the difference between annotations: @MemberGetter and @ValueGetter

here's SO thread of mine
Piotr

Samuel Audet

unread,
Nov 5, 2016, 12:22:26 AM11/5/16
to javacpp...@googlegroups.com
The problem with enums though is that in C++ they are integers, something the enum class in Java does not allow.
So, we cannot use that to map all functionality of C++.

We can however provide a higher level API based on that idea, if we know that the C++ library isn't going to use arbitrary integer values.
We could also try to provide automatically this kind of higher level wrappers as overloaded methods though. Would you like to try?

And I've answered your other question on Stack Overflow!

Samuel
--
You received this message because you are subscribed to the Google Groups "javacpp" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javacpp-proje...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages