What is the easiest way to call Objective-C code from Java?

3.8k Views Asked by At

I need to access a list of Wifi devices on Mac OSX from Java code and after researching it, I've found that I need to resort to "native" code - namely the CoreWLAN framework and the CWInterface.h class (https://developer.apple.com/library/mac/#documentation/CoreWLAN/Reference/CWInterface_reference/translated_content/CWInterface.html)

I initially thought I would be able to call this code using JNA but realized that I needed something since CoreWLAN is Objective-C (not C/C++).

I've tried this Objective-C Java bridge (https://github.com/shannah/Java-Objective-C-Bridge) but I can't work out how to make it find the CoreWLAN framework.

So I've also tried using JNAerator (https://code.google.com/p/jnaerator/wiki/ObjectiveC) so I can I use BridJ (https://code.google.com/p/bridj/), but I can't make it generate the right Java code.

  • Just using this style java -Xmx1000m -jar jnaerator.jar -framework CoreWLAN -jar CoreWlan.jar runs quickly but results in a jar that only contains mappings for CoreWlan.h
  • If I run jnaerator against CWInterface.h then jnaerator fails. (I'm using the latest snapshot version of jnaerator)

What is the best way to call methods on CWInterface.h from Java?

3

There are 3 best solutions below

0
On

You can use the java objective-c bridge for this. You just need to load the framework you want to use with jna's Native.loadLibrary() method.

This example uses the WebKit framework. https://github.com/shannah/Java-Objective-C-Bridge/blob/master/java/test/ca/weblite/objc/TestWebView.java

0
On

Personally I would do this via two totally separate programs that communicate via a shared memory mapped file. One program written in straight Objective-C, and the other in straight Java.

Memory mapping would mean that both programs would have access to the same region of memory, without having to resort to JNI at all.

Notes on memory mapping from Java:

http://javarevisited.blogspot.co.uk/2012/01/memorymapped-file-and-io-in-java.html

Notes on memory mapping from Objective C:

https://gist.github.com/jverkoey/2985830

That said, if you do want to do go the JNI route, then Apple has the following advice:

It is recommended that you use the Java JNI template in Xcode as a starting point for your JNI development.

To interoperate with the Objective-C runtime from JNI, link against JavaNativeFoundation.framework, which is a sub-framework of JavaVM.framework. It contains Objective-C classes and macros to automatically set up and tear down autorelease pools, catch and re-throw Java and Cocoa exceptions, hold JNI global references in Foundation container classes, and convert object graphs of strings, numbers, lists, maps, and sets.

The above quotes were taken from here:

https://developer.apple.com/library/mac/documentation/java/conceptual/java14development/Java14Development.pdf

0
On

What I would do is create a C++ class that communicates with the Java code through JNI. You can use both C++ and Obj-C in your xCode project. I haven't tried myself to use a Obj-C++ class with JNI, but I would just create a C++ class responsible for all communication between Java and Obj-C, this class can just be included in the Obj-C class where you need it (change the extension of this Obj-C file to .mm since it'll include C++ code).

I found this a helpful article on JNI: http://www.ibm.com/developerworks/java/tutorials/j-jni/