[sane-devel] RE: JSane

David Neary David@phenix.fr
Tue, 15 Jun 2004 16:19:37 +0200

Andi McLean said:
> On Sunday 13 June 2004 00:27, Klemens Dickbauer wrote:
> Dave what do you think about putting the JNI part in with my code?

If you can make sense of it, please feel free. The JNI wrappers are actually
quite trivial. The hardest thing is figuring out how to avoid memory leaks.
There are 2 ways to do this - expose allocation and deletion methods in the
C, or communicate how much space is needed to the Java side, and let the jvm
take care of garbage collection. The latter is the reason why I added the
convenience method "getNumberOfDevices" in the JNI wrappers, I think it has
a bug in it too. 

I think the correct implementation should have something like:

    devListLen = 0;
    while (device_list[devListLen] != NULL)
      devListLen ++;
    return devListLen;

the one I have seems to have an off-by-one error when there is at least one
device (I'm not sure I understand why, but it's the behaviour I'm seeing).

> Does it fit with the design I've created?

You're going to laugh, but because of continued problems with DLLs, I am now
convinced that the nest thing for me to do is to use your pure Java
implementation of the net protocol :)

I like your design, even though some of the class names are a bit
cumbersome, and I think that it's probably the best way to go for a Java

> > Anyway, having a direct Java interface to the sane libs seems also
> > desireable to me. David, what do you think about the 
> changes I suggest?

I missed this mail (I'm on a digest, so I occasionally overlook mails I
probably shouldn't). Sorry :)

> > An unexpected exception has been detected in native code 
> outside the VM.
> > Unexpected Signal : 11 occurred at PC=0x4DE37B06
> > Function=sane_dll_control_option+0x56
> > Library=/usr/lib/libsane.so.1

Looks like you're running on Linux or some other unix...

> > Current Java thread:
> > 	at 
> org.saneproject.scan.sane.Sane.getControlOption(Native Method)
> > 	[..]

Have you tried running the org.sane.Test class? Here's a sample usage of the
Sane bindings:

public class Test
    public static void main(String[] args) throws IOException
        Sane sane = new Sane();
        int version[] = new int[1]; // Array to get version #.
        int status = sane.init(version);
        if (status != Sane.STATUS_GOOD)
                "init() failed.  Status= " + sane.strstatus(status));
        System.out.println("VersionMajor =" +
        System.out.println("VersionMinor =" +
        System.out.println("VersionBuild =" +
        // Get list of devices.
        // Allocate room for 50.
        SaneDevice devList[] = new SaneDevice[50];
        status = sane.getDevices(devList, false);
        if (status != Sane.STATUS_GOOD)
                "getDevices() failed.  Status= " + sane.strstatus(status));
        for (int i = 0; i < 50 && devList[i] != null; i++)
                "Device '"
                    + devList[i].name
                    + "' is a "
                    + devList[i].vendor
                    + " "
                    + devList[i].model
                    + " "
                    + devList[i].type);
	  // Sanity test over... clean up

Your code should look very similar to the C code equivalent:

sane.init (version);
  sane.open (device);
    sane.getControlOption(); // Get options
    sane.setControlOption(); // Set option value

      repeat sane.read();
      return to sane.start() if we need more pages

You can also compile the C code with -g and run java in a debugger to get a
better idea of what's going on.

Hope this all helps,