Solved

array arguments

Posted on 2001-08-20
10
358 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
 

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
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 19

Accepted Solution

by:
Jim Cakalic earned 20 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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

707 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now