Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 372
  • Last Modified:

array arguments

Is there an easier way than the following?

int i=func(arg1, arg2, index[0], index[1], index[2], index[3],...,index[99]);
0
samliam
Asked:
samliam
1 Solution
 
Jim CakalicSenior Developer/ArchitectCommented:
You could pass the array itself:

    int i = func(arg1, arg2, index);

Then the method could handle all the array access. You don't even have to pass the number or items in the array (unless you want the method to process only part of it) because all array objects know and can report their length as a public int length.

Or perhaps I misunderstand the question?

Best regards,
Jim Cakalic
0
 
hquocCommented:
Hi samliam,
u should not use an array directly. In java, i think that u should use a vector object such below:
Vector arg1, arg2;
int func(arg1,arg2);
And then in the definition 'func', u will use an         Enumeration object to make the iterator variable:
Enumeration index = arg1.elements();
while (index.hasMoreElements()) {
       index.nextElement();
       //your code here
}

Hope it will help u,
regards,
huuquoc
0
 
kotanCommented:
It's not necessary to use vector.
You can use array.

let say, the index datatype is int.
int index[] = new int[100];

the func():

public int func(String arg1, String arg2, int[] inx)
{
     for (int i = 0; i < inx.length; i++)
     {
          // deal with inx[i].
     }

     return 0;
}

To call func(),
int i = func(arg1, arg2, index);
like what jim_cakalic gave.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
samliamAuthor Commented:
I tried "func(arg1, arg2, index)" in the beginning and the compiler could not "resolve the symbol func".

If I replace the 'index' with, e.g., '2,2,2', it works fine.

The function signatures are:
public native int func(String, String, int);
public native int func(String, String, int, int);
  ..., etc.
0
 
samliamAuthor Commented:
Error message is: "cannot resolve symbol func(String, String, int[])"
I defined the (variable-length) array with given input..
0
 
Jim CakalicSenior Developer/ArchitectCommented:
Ah, yes, I see now. You have significantly less latitude because you are calling native methods (JNI methods) with signatures that require a specific number of arguments. If this is the way that the native interface was designed and you don't control the implementation then you are stuck with breaking up the array into its constituent elements when you call the method. However, if the native interface -- the JNI implementation -- can be changed, then there is no reason that you cannot have a method with the signature:

    public native int func(String, String, int[]);

that would map to a JNI C++ method:

    JNIEXPORT jint JNICALL Java_func(JNIEnv *, jobject, jstring, jstring, jintArray);

Certainly, this would be much preferred to 100 methods which take increasing numbers of int arguments depending on the size of the Java array.

Best regards,
Jim Cakalic
0
 
samliamAuthor Commented:
so why can you call with just 'index' instead of all elements one by one? and why is it different with JNI?
0
 
Jim CakalicSenior Developer/ArchitectCommented:
At compile time, the Java compiler determines which overloaded method it will call by matching the signature of the method call with those defined by the target class or one of its superclasses. A method signature is the combination of its name, arguments types and argument order (but does not include return type). So as described by you previously, you have a number of overridden methods declared:

    public native int func(String, String, int);
    public native int func(String, String, int, int);
    public native int func(String, String, int, int, int);
    ...
    public native int func(String, String, int, ... , int);

so that you can call the func method with two Strings and varying numbers of ints depending, I guess, on the size of the Java array which your application is holding. Correct me where I am wrong because I'm working on the assumption that what you really wanted all along was a single function that you could call with an array of ints.

For each of the above method declarations, there is a corresponding JNI method with a "matching" signature:

    JNIEXPORT jint JNICALL Java_func(JNIEnv *, jobject, jstring, jstring, jint);
    JNIEXPORT jint JNICALL Java_func(JNIEnv *, jobject, jstring, jstring, jint, jint);
    JNIEXPORT jint JNICALL Java_func(JNIEnv *, jobject, jstring, jstring, jint, jint, jint);
    ...
    JNIEXPORT jint JNICALL Java_func(JNIEnv *, jobject, jstring, jstring, jint, ... , jint);

Given this set of method signatures and the assumption that your application has an int[] holds ints that serve as arg values to the methods, you have to code a switch that "selects" the correct method to call based on the number of elements in the array. The Java compiler will ensure that methods with the specified signature actually exists while compiling the class. This really isn't any different for native methods than it is for Java methods.

The hard part is declaring a native method that takes a Java array and then using the array in the method. There is a special JNI arg type for each primitive array type and one for Object type. So, as I indicated previously, if you are writing the C++ code that implements the native methods referred to in your Java class, you can add the following to your Java class:

    public native int func(String, String, int[]);

and to your C++ implementation:

    JNIEXPORT jint JNICALL Java_func(JNIEnv *, jobject, jstring, jstring, jintArray) {
        // your C++ method
    }

Now, when you code:

    String str1 = "abc";
    String str2 = "xyz";
    int[] index = new int[50];
    int x = func(str1, str2, index);

there will actually be a func method that takes two Strings and an int[] so the compiler will not complain "cannot resolve symbol func(String, String, int[])" because there will in fact be a func method with the correct signature.

The Java Tutorial trail on JNI provides additional material and examples of using Java arrays in native methods.
    http://web2.java.sun.com/docs/books/tutorial/native1.1/implementing/array.html

Jim
0
 
samliamAuthor Commented:
Sorry, I didn't make it clear.

I understand what you are saying. I was just asking a basic question: (not JNI-specific)

why can I use
func("a","b",index)
to replace
func("a","b",index[0],index[1],index[3],....);

in other words, why can I just use the name of the array? In c++, the name of an array is a pointer to the starting point of the array, and functions are called by reference, so I can pass a pointer as an argument.

What's the case with Java?
0
 
Jim CakalicSenior Developer/ArchitectCommented:
A Java array is an object. As such, all use of the array is by reference -- not exactly the same thing as a pointer but reasonably analogous. When you call a method that takes an object argument, a temporary variable is created to hold a copy of the reference to the target object and that temporary variable is provided as the argument value to the method. Any change to the underlying object through the reference is visible after the method completes. But changes made to the variable holding the reference are _not_ visible.

So, you can pass an array to a method just like you can pass a String object to a method. You can operate on the array within the method using identical syntax to operations performed outside the method. Changes made to array elements will be visible after the method completes. But if you attempt to allocate a new array and assign it to the method parameter variable, that change will only be effective within the method until the method completes, then it will be lost.

In summary, it is similar to C++ but not identical. A Java array is an object -- not some blob of memory which can be addressed as you please. But because it is an object, you can pass a reference to the array to a method for it to operate upon.

Jim
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now