Google Groups Home
Help | Sign in
JNI - Passing and returning complex values
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 26 - Collapse all   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
adityar7  
View profile
 More options Jul 3, 10:34 pm
Newsgroups: comp.lang.java.programmer
From: adityar7 <adity...@gmail.com>
Date: Thu, 3 Jul 2008 19:34:30 -0700 (PDT)
Local: Thurs, Jul 3 2008 10:34 pm
Subject: JNI - Passing and returning complex values
I'm a C programmer with limited Java experience, and need to use JNI
to implement a library in Java on top of a C library that consists of
a bunch of functions, each receiving some parameters from the
operating system. For each C function, the corresponding Java method
will be called, and some values would be returned back to the C
function. i.e. C -> Java -> C.

I know how to deal with simple primitive types, but I need to pass and
return multiple fields which could be primitive types or C structs. I
understand that to pass C structs I would need to define a
corresponding Java class and copy over the struct fields.

The question, though, is how to deal with multiple parameters/return
values of different types. Here is a sample C function specification:

int getattr (const char *, struct stat *)

I have approximately 35 such functions with differing number and types
of parameters. The corresponding Java method needs to be passed both
these parameters, and it also needs to return both of them! Since I'm
new to JNI the only way I can think of is to define 35 Java classes,
each corresponding to a particular set of parameters. Hopefully there
is a better way to do it!

Any help would be greatly appreciated :D


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Arne Vajhøj  
View profile
 More options Jul 3, 10:46 pm
Newsgroups: comp.lang.java.programmer
From: Arne Vajhøj <a...@vajhoej.dk>
Date: Thu, 03 Jul 2008 22:46:05 -0400
Local: Thurs, Jul 3 2008 10:46 pm
Subject: Re: JNI - Passing and returning complex values

You can put all the native methods in one class.

But if you need 35 different classes with data, then I can not
see any way to avoid writing them.

Arne


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
marlow.and...@googlemail.com  
View profile
(1 user)  More options Jul 4, 7:18 am
Newsgroups: comp.lang.java.programmer
From: marlow.and...@googlemail.com
Date: Fri, 4 Jul 2008 04:18:08 -0700 (PDT)
Local: Fri, Jul 4 2008 7:18 am
Subject: Re: JNI - Passing and returning complex values
On 4 Jul, 03:34, adityar7 <adity...@gmail.com> wrote:

> I'm a C programmer with limited Java experience, and need to use JNI
> to implement a library in Java on top of a C library
> The question, though, is how to deal with multiple parameters/return
> values of different types. Here is a sample C function specification:

> int getattr (const char *, struct stat *)

I recommend SWIG. See www.swig.org. This is what I used to interface
to a proprietary C library for a server that we wanted to be in java.
SWIG would take the prototype above and create corresponding java
classes for where there is no natural mapping, e.g it would create a
class for stat.

Output from SWIG is in the form of two files, one is C glue to go into
a dynamic library, the other is the java class that contains all the
methods for the functions you want to call. Other java files are
created for the new classes it creates, like stat. Your java program
has to load the dynamic library first.

Regards,

Andrew Marlow


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Roedy Green  
View profile
(1 user)  More options Jul 4, 8:54 am
Newsgroups: comp.lang.java.programmer
From: Roedy Green <see_webs...@mindprod.com.invalid>
Date: Fri, 04 Jul 2008 12:54:43 GMT
Local: Fri, Jul 4 2008 8:54 am
Subject: Re: JNI - Passing and returning complex values
On Thu, 3 Jul 2008 19:34:30 -0700 (PDT), adityar7 <adity...@gmail.com>
wrote, quoted or indirectly quoted someone who said :

>I have approximately 35 such functions with differing number and types
>of parameters. The corresponding Java method needs to be passed both
>these parameters, and it also needs to return both of them! Since I'm
>new to JNI the only way I can think of is to define 35 Java classes,
>each corresponding to a particular set of parameters. Hopefully there
>is a better way to do it!

This is one of the uglier parts of Java.  It supports multiple inputs
to a method but only one output.

How to kludge?

one way is to return an array of double or array of objects.  You to
lose typing and keyword identification of results.

Another approach is to create a class with a number of internal
variables.  To use it you call setXXX to set each of the inputs, then
call calcXXX  to calculate.  Then call getXXX to get each of the
results.  This is the most Javaesque solution.

It is considered bad form to create result classes of scattered crap
that is not logically related.  

Have your method return a result, and if there is a problem throw an
exception, rather than returning a result and status as you would in
C.

Rethink your methods so that there are a small number of possible
result classes that have physical meaning.

They problem you are having is made worse if you try to write C in
Java, rather than thinking OO.
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
marlow.and...@googlemail.com  
View profile
 More options Jul 4, 9:18 am
Newsgroups: comp.lang.java.programmer
From: marlow.and...@googlemail.com
Date: Fri, 4 Jul 2008 06:18:19 -0700 (PDT)
Local: Fri, Jul 4 2008 9:18 am
Subject: Re: JNI - Passing and returning complex values
On 4 Jul, 13:54, Roedy Green <see_webs...@mindprod.com.invalid> wrote:

> This is one of the uglier parts of Java.  It supports
> multiple inputs to a method but only one output.

> How to kludge?

> Another approach is to create a class with a number of internal
> variables.

This is what SWIG does. The classes it creates has setters and
getters. You have to write a very thin C wrapper which calls the C
code you first thought of. The wrapper also manages this way of
interfacing. The C code will have to populate the structure ready for
return, your java code just puts the result into an object of the type
generated by SWIG. You use the getters to obtain the member values.

I reckon this is MUCH easier than doing raw JNI code.

-Andrew Marlow


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lew  
View profile
 More options Jul 4, 9:39 am
Newsgroups: comp.lang.java.programmer
From: Lew <l...@lewscanon.com>
Date: Fri, 04 Jul 2008 09:39:19 -0400
Local: Fri, Jul 4 2008 9:39 am
Subject: Re: JNI - Passing and returning complex values

SWIG sounds like a real find.  Thanks for bringing it to our attention.

Regarding the example with the 'stat' struct, does SWIG let you turn that into
a convention-compliant type name, 'Stat'?

--
Lew


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
marlow.and...@googlemail.com  
View profile
 More options Jul 4, 10:54 am
Newsgroups: comp.lang.java.programmer
From: marlow.and...@googlemail.com
Date: Fri, 4 Jul 2008 07:54:01 -0700 (PDT)
Local: Fri, Jul 4 2008 10:54 am
Subject: Re: JNI - Passing and returning complex values
On 4 Jul, 14:39, Lew <l...@lewscanon.com> wrote:

Yes it does. I must admit, I am suprised when java people tell me they
don't know about SWIG. I am relatively new to java and I was lukcily
to come across it quite early. I saw it used about a year ago on a C++
project where suddenly a java interface was required by certain
customers. It was quickly knocked up using SWIG. The C++ was concerned
mainly with returning structures that represented trades for
particular financial instruments. Each instrument had its own type and
several were expressed in terms of other types.

-Andrew Marlow


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lew  
View profile
 More options Jul 4, 11:01 am
Newsgroups: comp.lang.java.programmer
From: Lew <l...@lewscanon.com>
Date: Fri, 04 Jul 2008 11:01:39 -0400
Local: Fri, Jul 4 2008 11:01 am
Subject: Re: JNI - Passing and returning complex values

marlow.and...@googlemail.com wrote:
> project where suddenly a java interface was required by certain
> customers. It was quickly knocked up using SWIG.

Aside:  I enjoyed the momentary mental hiccough - "knocked up" as you meant it
is a regional expression meaning "built" or "prototyped".  Around these parts
it means "impregnated", usually with an implication of out-of-wedlock
relations.  Often the latter sense is quickly achieved after a few swigs of
something intoxicating.

--
Lew


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tom Anderson  
View profile
(1 user)  More options Jul 4, 11:12 am
Newsgroups: comp.lang.java.programmer
From: Tom Anderson <t...@urchin.earth.li>
Date: Fri, 4 Jul 2008 16:12:32 +0100
Local: Fri, Jul 4 2008 11:12 am
Subject: Re: JNI - Passing and returning complex values

Well, firstly, are you aware that there is already a java binding of FUSE?

http://sourceforge.net/projects/fuse-j/

If you don't want to use that, or if this isn't what you're working on, to
answer your question, i'd do a straightforward conversion of the C
interface, and pass a writeable object from C to java, get java to write
into it, then copy back from the java object to the C one. Like so:

// java:

public class Stat {
        public int ino ;
        // etc

}

public interface Filesystem {
        public int getattr(String path, Stat sb) ;

}

public class FUSEManager {
        static {
                System.loadLibrary("fuse") ;
        }
        public static native void init(Filesystem fs) ;

}

// C:

/* error checking omitted for clarity! */

#define OK 0

JavaVM *jvm ; // JVM ref, get in a setup method

jobject fs ; // ref to a Filesystem object, get in a setup method
jclass fsClass ;
jmethodID getattrID ;

jclass statClass ;
jmethodID statCtorID ;
jfieldID statInoID ;
// etc for other fields

JNIEXPORT void JNICALL Java_FUSEManager_init(JNIEnv *env, jclass class, jobject _fs) {
        (*env)->GetJavaVM(env, &jvm) ;
        fs = (*env)->NewGlobalRef(env, _fs) ;
        jclass _fsClass = (*env)->GetObjectClass(env, fs) ;
        fsClass = (*env)->NewGlobalRef(env, _fsClass) ;
        getattrID = (*env)->GetMethodID(env, fsClass, "getattr", "(Ljava/lang/String;LStat;)I") ;
        jclass _statClass = (*env)->FindClass(env, "com/mypackage/Stat") ;
        statClass = (*env)->NewGlobalRef(env, _statClass) ;
        statCtorID = (*env)->GetMethodID(env, statClass, "<init>", "()V") ;
        statInoID = (*env)->GetFieldID(env, statClass, "ino", "I") ;
        // etc for other fields

}

void copyStatIn(JNIEnv *env, jobject statObj, struct stat *stat) {
        stat->st_ino = (*env)->GetIntField(env, statObj, statInoID) ;
        // etc for other fields

}

// would define a copyStatOut for setattr

int getattr(const char *path, struct stat *stat) {
        JNIEnv *env = NULL ;
        (*jvm)->AttachCurrentThread(jvm, &env, NULL) ;
        jstring pathStr = (*env)->NewStringUTF(env, path) ;
        jobject statObj = (*env)->NewObject(env, statClass, ctorID) ;
        /* i don't copy the struct into the object here - hope this is right */
        jint ret = (*env)->CallIntMethod(env, fs, getattrID, pathStr, statObj) ;
        /* don't copy back if call failed */
        if (ret == OK) copyStatIn(statObj, stat) ;
        /* don't think we need to release local refs explicitly before detach */
        (*jvm)->DetachCurrentThread(jvm) ;
        return ret ;

}

Does that make sense? This means defining one class per struct, plus one
copy-in method and one copy-out method, as needed. No need to write 35
different classes!

I've assumed that, despite what you said, the const char* parameter isn't
'returned' in any sense.

tom

--
Know who said that? Fucking Terrorvision, that's who. -- D


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
adityar7  
View profile
 More options Jul 4, 9:10 pm
Newsgroups: comp.lang.java.programmer
From: adityar7 <adity...@gmail.com>
Date: Fri, 4 Jul 2008 18:10:53 -0700 (PDT)
Local: Fri, Jul 4 2008 9:10 pm
Subject: Re: JNI - Passing and returning complex values
On Jul 4, 4:18 am, marlow.and...@googlemail.com wrote:

Sounds excellent. I have seen that term (SWIG) often but not being a
regular Java programmer, didn't know what that means. I'll check it
out and see how it goes. Thanks for pointing it out!

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
adityar7  
View profile
 More options Jul 4, 9:21 pm
Newsgroups: comp.lang.java.programm