Solved

array arguments

Posted on 2001-08-20
10
363 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

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 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

Independent Software Vendors: 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!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
null output 3 59
Selenium docs api java index 3 98
running on tomcat not jboss eap 7.0 3 55
Strange router problem - can't access hotmail.com 14 109
An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
Suggested Courses

752 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