Exception when trying to use JNA Structure in Scala

664 views
Skip to first unread message

Bolek

unread,
Jun 17, 2014, 1:36:21 PM6/17/14
to scala...@googlegroups.com
I am trying to call native code from Scala through JNA, and stumbled upon following problem:
Simple Scala wrapper for C struct, defined as follows:

import com.sun.jna.{Library, Native, Platform, Structure, Pointer}

import scala.collection.JavaConverters._

class Test(var t:Int, var s:Int) extends Structure { override def getFieldOrder = List("t","s").asJava }


compiles fine, but at runtime throws with 

var t = new Test(1,2)

java.lang.Error: Structure.getFieldOrder() on class Test returns names ([s, t]) which do not match declared field names ([])


Looking at jna-4.1.0 source code, and the offending fragment, everything should to be fine (similar steps executed from REPL yields list of fields), yet it is not :/ 

I would appreciate if someone could help me deal with this error...


Rex Kerr

unread,
Jun 17, 2014, 1:47:53 PM6/17/14
to Bolek, scala-user
Scala accesses all fields through accessors instead of directly.  So you do have t and s fields, but they are private, and are accessed publicly via methods int t(); and void t_$eq(int);.  You can see this if you
  javap -c -l -s -private Test
after you compile your class.

I'm not sure of a good workaround for this; I've only used JNI, not JNA.  Marking the fields final is not enough to allow direct field access.  You may have to create the structs in Java.

  --Rex


--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Bolek

unread,
Jun 18, 2014, 6:00:28 AM6/18/14
to scala...@googlegroups.com, bteki...@gmail.com
Indeed, JNA assumes that fields are public,
...
for (int i=0;i < fields.length;i++) {
                int modifiers = fields[i].getModifiers();
                if (Modifier.isStatic(modifiers)
                    || !Modifier.isPublic(modifiers))
                    continue;
                classFields.add(fields[i]);
            }
...
so this won't work with Scala... It seems that the only reasonable way to work with native code would to be to create a java/JNA wrapper and call it from Scala.
Thanks for your help,
Bolek.

Sanjay Dasgupta

unread,
Jun 19, 2014, 3:13:40 AM6/19/14
to scala...@googlegroups.com, bteki...@gmail.com
I used to maintain a version of JNA's "Structure.java" that was suitable for use from Scala, but unfortunately have not had the time to keep it up to date for a while.

I recently looked an JNA again (version 4.0.0), and updated Scala Native Access's version of "Structure.java". The rest of the Scala Native Access site has not yet been updated, so the examples and other code will still not work. But if a working version (for Scala) of  "Structure.java" is all you need, please give SNA's Structure.java a try. The code is based on JNA 4.0.0, and you can find all the changes by searching for "SDG". 

If you do get around to using it, please let me know any problems (and successes) you have.

Regards,

- Sanjay

Bolek

unread,
Jun 23, 2014, 5:54:58 AM6/23/14
to scala...@googlegroups.com, bteki...@gmail.com
Hi Sanjay,
Thank you for the information, I will give your code a try. Is there a simple way in which one can start with your version of SNA, other then compiling JNA from scratch, with your code injected?
Best,
Bolek.

Sanjay Dasgupta

unread,
Jun 24, 2014, 6:08:42 AM6/24/14
to scala...@googlegroups.com, bteki...@gmail.com
Hi Bolek,

In a test that I ran with the modified Structure.java, I did not have to recompile all of JNA at all. The test project had the following elements: 

1) include the JNA jar (I used 4.0.0) as a dependency.
2) the src tree had a directory (package) for the modified Structure.java (as if it were part of the project's own sources). 
3) the project's own sources were in the src tree at their usual places

Everything seemed to work just fine. My native-structure definitions in Scala were defined as objects extending Structure.

I will post the example project at the scala-native-access website later today.

Regards,

- Sanjay

Sanjay Dasgupta

unread,
Jun 24, 2014, 3:07:03 PM6/24/14
to scala...@googlegroups.com, bteki...@gmail.com
The Scala Native Access site now has a fully refurbished description of a JNA-4.0.0 compatible capability. 

A few simple demo programs are provided in a sbt compatible directory structure that can be adapted for other projects.

A very short user guide is also available.

- Sanjay
Reply all
Reply to author
Forward
0 new messages