tarzanking / javacpp

Automatically exported from code.google.com/p/javacpp
GNU General Public License v2.0
0 stars 0 forks source link

Add @Raw annotation for instances where the raw jobject should be passed to C++ #13

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Write a C++ method that expects a jobject (actual JVM object)...
2. Try every means known to get it to generate successfully.
3. Receive warnings on generation that you are using an unsupported type.
4. Receive errors on compilation because (in this instance) the parameter being 
passed generates code like the following:

JNIEXPORT void JNICALL Java_com_xxx_XXX_yyy_YYY_00024ZZZ_zzz(JNIEnv* e, jobject 
o, jobject p0) {
    YYY::ZZZ* pointer = (YYY::ZZZ*)jlong_to_ptr(e->GetLongField(o, JavaCPP_addressFieldID));
    if (pointer == NULL) {
        e->ThrowNew(JavaCPP_getClass(e, 1), "This pointer address is NULL.");
        return;
    }
    jint position = e->GetIntField(o, JavaCPP_positionFieldID);
    pointer += position;
     pointer0 = p0;  <--- this is the key line, no type is declared for pointer0 because the intention was to pass the raw jobject
    try {
        pointer->setNodeWrapper(pointer0);
    } catch (...) {
        JavaCPP_handleException(e);
    }
}

What is the expected output? What do you see instead?

JNIEXPORT void JNICALL Java_com_xxx_XXX_yyy_YYY_00024ZZZ_zzz(JNIEnv* e, jobject 
o, jobject p0) {
    YYY::ZZZ* pointer = (YYY::ZZZ*)jlong_to_ptr(e->GetLongField(o, JavaCPP_addressFieldID));
    if (pointer == NULL) {
        e->ThrowNew(JavaCPP_getClass(e, 1), "This pointer address is NULL.");
        return;
    }
    jint position = e->GetIntField(o, JavaCPP_positionFieldID);
    pointer += position;
    jobject pointer0 = p0;  <--- this is the key line, the type is declared for pointer0 as a jobject
    try {
        pointer->setNodeWrapper(pointer0);
    } catch (...) {
        JavaCPP_handleException(e);
    }
}

What version of the product are you using? On what operating system?
2012-02-18

Please provide any additional information below.
Would be a huge deal from my perspective. I've verified that the behavior if 
the source is modified is as desired. (Generate cpp, modify, build without 
regenerating, test).

Original issue reported on code.google.com by david.sc...@gmail.com on 29 Mar 2012 at 8:13

GoogleCodeExporter commented 9 years ago
The function would also need the JNIEnv, no? What would be the cleanest way of 
doing that in your opinion?

Original comment by samuel.a...@gmail.com on 29 Mar 2012 at 10:31

GoogleCodeExporter commented 9 years ago
In my particular situation, knowledge of the JNIEnv is handled within the 
library being interacted with. The interactions are around cocos2d-x which 
offers its own C++ JNI helper to ease issues related to obtaining the JNIEnv. 
However, as instance methods are required here I need a means of providing the 
object front the runtime to the C++ class for use in invocations. 

My line of thinking was, if this is needed great pains have already been taken 
to account for passing raw JVM objects to C++. Dealing with the details doesn't 
seem like it should be an issue for JavaCPP. 

-Dave

David Schaefgen
Raconteur

t: +1 901 264-9646
e: david.schaefgen@gmail.com (mailto:david.schaefgen@gmail.com)

Original comment by david.sc...@gmail.com on 29 Mar 2012 at 10:39

GoogleCodeExporter commented 9 years ago
No it's not an issue, I thought about that before as well. It's just that 
usually we are going to need the JNIEnv and I am not sure what would be the 
best way to pass it along...

Original comment by samuel.a...@gmail.com on 29 Mar 2012 at 11:31

GoogleCodeExporter commented 9 years ago
I mean, someone who starts using JavaCPP standalone without other tools and 
sees that we can pass raw objects is going to have a hard time understanding 
why we can't access the JNIEnv, which gets passed along the function anyway. 
It's just not consistent. I'd like to make it consistent before committing to a 
given design. If you have ideas, they would be most welcome!

Original comment by samuel.a...@gmail.com on 29 Mar 2012 at 11:36

GoogleCodeExporter commented 9 years ago
Let me know how this sounds. We could add a boolean withEnv value to the @Raw 
annotation, such that if at least one of the @Raw annotation associated with a 
method or its parameters looks like @Raw(withEnv=true), then JavaCPP assumes 
the first two parameters of the native function are JNIEnv* and jobject/jclass, 
and calls it accordingly? Of course, the idea is to default withEnv=false...

Original comment by samuel.a...@gmail.com on 31 Mar 2012 at 6:09

GoogleCodeExporter commented 9 years ago
That's actually a pretty much identical thought to where I was after you 
mentioned wanting to provide for the "true" situation. I think this is fairly 
effective and as with any @Raw scenario would require the C++ API to be thought 
out accordingly. Either you do need the Env and object/class or you don't.

-Dave

David Schaefgen
Raconteur

t: +1 901 264-9646
e: david.schaefgen@gmail.com (mailto:david.schaefgen@gmail.com)

Original comment by david.sc...@gmail.com on 31 Mar 2012 at 1:22

GoogleCodeExporter commented 9 years ago
Ok, I've added this functionality in the code I've just checked in the 
repository:
http://javacpp.googlecode.com/git/javacpp/src/main/java/com/googlecode/javacpp/a
nnotation/Raw.java
http://javacpp.googlecode.com/git/javacpp/src/main/java/com/googlecode/javacpp/G
enerator.java
Let me know if it does what it's supposed to do, thanks!

Original comment by samuel.a...@gmail.com on 8 Apr 2012 at 12:34

GoogleCodeExporter commented 9 years ago
The change behaves as expected. I added a case on my end that would need the 
environment passed as well to confirm that it behaves as we discussed. It looks 
good on all fronts.

-Dave

David Schaefgen
Raconteur

t: +1 901 264-9646
e: david.schaefgen@gmail.com (mailto:david.schaefgen@gmail.com)

Original comment by david.sc...@gmail.com on 9 Apr 2012 at 5:33

GoogleCodeExporter commented 9 years ago
Great to hear that! Will put it in the next release.

BTW, how do you do your tests? Do you simply check that the compiler succeeds 
against some predefined test functions in C++ for all the features you require? 
In that case, I guess JavaCV itself is my unit test for JavaCPP :)

Original comment by samuel.a...@gmail.com on 10 Apr 2012 at 7:53

GoogleCodeExporter commented 9 years ago
Feature incorporated in the latest release!

Original comment by samuel.a...@gmail.com on 12 May 2012 at 11:20

GoogleCodeExporter commented 9 years ago
Issue 21 has been merged into this issue.

Original comment by samuel.a...@gmail.com on 7 Jun 2012 at 1:19