Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

array arguments

Posted on 2001-08-20
10
Medium Priority
?
370 Views
Last Modified: 2012-08-14
Is there an easier way than the following?

int i=func(arg1, arg2, index[0], index[1], index[2], index[3],...,index[99]);
0
Comment
Question by:samliam
10 Comments
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 6407797
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
 

Expert Comment

by:hquoc
ID: 6408319
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
 
LVL 6

Expert Comment

by:kotan
ID: 6408385
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:samliam
ID: 6409495
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
 

Author Comment

by:samliam
ID: 6409532
Error message is: "cannot resolve symbol func(String, String, int[])"
I defined the (variable-length) array with given input..
0
 
LVL 19

Accepted Solution

by:
Jim Cakalic earned 80 total points
ID: 6410332
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
 

Author Comment

by:samliam
ID: 6410576
so why can you call with just 'index' instead of all elements one by one? and why is it different with JNI?
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 6410728
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
 

Author Comment

by:samliam
ID: 6410897
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
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 6410936
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

Ask an Anonymous Question!

Don't feel intimidated by what you don't know. Ask your question anonymously. It's easy! Learn more and upgrade.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Suggested Courses

971 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question