Dabbler
Dabbler

Reputation: 9863

JNI - How to modify a parameter when calling a Java method from C++?

I have a Java method something like this

public boolean ReadBool(String ValueName, Boolean Value)  
{  
  boolean Retval = ...;  
  ...  
  Value = true;  
  ...  
  return bRetval;  
}

that I call from native code (C++) like this:

jMethodID MethodId = pEnv->GetMethodID(ClassId, "ReadBool", "(Ljava/lang/String;Ljava/lang/Boolean;)Z");  
// What goes instead of "??" ?  
bool bOk = pEnv->CallBooleanMethod(myobject, MethodId, pEnv->NewStringUTF("Value1"), "??");

My intention is for the Java method to "return" a boolean value in Value. I understand that a built-in boolean will not work for this purpose. Is it possible to do this with a Boolean wrapper? How does one construct the object to pass in place of "??" ?

I have googled around, but some questions remain. For example, I suppose I could pass an object created by calling Boolean's <init> "method". But wouldn't the assignment in the Java ReadBool make Value refer to a newly created wrapper, throwing away that first object? In that case I would have called <init> for nothing. I think it should be possible to create (in the native code) something that Java sees as an object that is null and whose type is Boolean. Is that possible? Or am I on the wrong track altogether?

Upvotes: 2

Views: 1957

Answers (1)

Voo
Voo

Reputation: 30216

Booleans are immutable in Java, so you need your own wrapper class, which can be really simple though:

public class BooleanWrapper {
    public boolean val;
    // public is fine here imo, but you can obviously use [g|s]etters as well
}

Or if you don't want this, we can use a.. well not really pretty, but nice to know hack:

public void hack(boolean[] vals) {
    vals[0] = true; // voila, now you change the value itself
}

Has some obvious drawbacks when calling (and looks strange), but if you're fine with keeping a specific parameter sequence, you can do:

public void hack(boolean.. vals) {
    vals[0] = true; // voila, now you change the value itself
}

that way the caller doesn't have to use stuff like new boolean[] {};

You can obviously cheat and change the internal state of the Boolean object itself, but that will have unwanted consequences (booleans are cached ergo if you change the Boolean.TRUE instance to false internally this will give interesting results). So don't do that.

Upvotes: 3

Related Questions