2

I am helping to code a stop-motion program that is to be cross platform, and on windows it works great. For those who do not know, stop motion is just a fancy term for animation. This program allows users to plug in Nikons, Canons, and Webcams into the computer, and have the program display a live view of the scene, and then have the ability to manually control the camera from there. Included is a framework file from canon for the camera, with a path defined as shown

import com.sun.jna.Native;
initialization and such

public static EdSdkLibrary EDSDK = (EdSdkLibrary) Native.loadLibrary("Macintosh/EDSDK.framework/EDSDK",EdSdkLibrary.class, options);

The error is thrown at the "public static int..." saying that the image is not found. I have tried numerous times redefining the path, moving the framework, and using various other frameworks identical to the one I'm using. Remember, this works flawlessly on Windows, but on Mac there is a problem.

Are frameworks different on macs, or are they to be defined differently? I have looked and found no other solutions.

EDIT: Okay, I defined the path and it now has this symbol > with no text next to it. WHat do I do now?

EDIT: It is saying that this % is not a command. Without it, it still fails to work.

Wolfgang Fahl
  • 15,016
  • 11
  • 93
  • 186
user2221529
  • 53
  • 1
  • 1
  • 4
  • You're probably trying to load the 32-bit library with a 64-bit JVM. Either run your JVM with `-d32` or load the 64-bit version of the EDSDK (EDSDK_64 in the download). – technomage Mar 31 '13 at 05:36

2 Answers2

3

JNA will successively attempt to load frameworks from ~/Library/Frameworks, /Library/Frameworks, and /System/Library/Frameworks, based on the core framework name (EDSDK in this case).

If the loadLibrary call succeeds, then the library was found. If the library was not found, you'll get an UnsatisfiedLinkError.

Frameworks are basically bundles of a shared library with other resources; ESDK.framework/ESDK is the actual shared library (for frameworks, OSX omits the "dyld" suffix normally found on a shared library on OSX).

EDIT

Here's how to make a symlink so that the paths look more like what JNA is expecting. From a terminal (run Terminal.app):

% ln -s /your/complete/path/to/Macintosh/EDSDK.framework ~/Library/Frameworks/EDSDK.framework

When this is done successfully, you should see the following when listing (ls) the symlink:

% ls -l ~/Library/Frameworks/EDSDK.framework
lrwxrwxr-x  1 YOU  YOU  50 Mar 31 01:13 /Users/YOU/Library/Frameworks/EDSDK.framework -> /your/complete/path/to/Macintosh/EDSDK/Framework/EDSDK.framework

You should see the symlink path (where JNA will look) on the left, with the path to the real file on the right. If not, delete the symlink file and try again. Note that you may need to create the directory ~/Library/Frameworks first; it may not yet exist.

Finally, make sure that the library you're trying to load matches the VM you're trying to load with; 64-bit with 64-bit, 32-bit with 32-bit. Canon does not provide a universal binary of their library, so you'll need to point to one or the other or merge the two using lipo.

technomage
  • 9,861
  • 2
  • 26
  • 40
  • Okay. So the error is not from a misdefined path, and I think that I have found the problem, but I don't know how to fix it: the error is stating that there is a missing .dylib file from the framework path, so how would I go about changing what it looks for from a .dylib to a .framework? – user2221529 Mar 29 '13 at 14:52
  • If the path doesn't look exactly like ESDK.framework/ESDK, then you can provide the relative path that includes ".framework" and it will be used verbatim (looking in the paths noted above). What path are you giving to `loadLibrary`? – technomage Mar 29 '13 at 15:03
  • the local library of the folder starting with Macintsoh then EDSDK.framework. I am not including the downloads folder in the path. This is the error "Unable to load library 'Macintosh/EDSDK.framework': dlopen(libMacintosh/EDSDK.framework.dylib, 9): image not found" – user2221529 Mar 29 '13 at 15:30
  • Put EDSDK.framework into ~/Library/Frameworks or one of the system frameworks paths, otherwise JNA attempts to load it it as a regular shared library instead of a framework. – technomage Mar 29 '13 at 15:59
  • Make a symlink from ~/Library/Frameworks/EDSDK.framework to /path/to/Macintosh/EDSDK.framework, then call `loadLibrary` with the name "ESDK". – technomage Mar 30 '13 at 11:51
  • What is a symlink? I'm sorry, I haven't done this before. How would I do that? – user2221529 Mar 30 '13 at 13:35
  • A symlink is a system link, right? If so, would I just give the local path of the framework on the second definition of the directory, and furthermore, would this code suffice? Path newLink = ...; Path existingFile = ...; try { Files.createLink(newLink, existingFile); } catch (IOException x) { System.err.println(x); } catch (UnsupportedOperationException x) { // Some file systems do not // support adding an existing // file to a directory. System.err.println(x); } – user2221529 Mar 30 '13 at 13:48
  • 'code' import java.io.IOException; import java.io.PrintWriter; public class SymlinkCreator { private Process process; private PrintWriter out; public SymlinkCreator( String path ) throws IOException { process = Runtime.getRuntime().exec(path); out = new PrintWriter(process.getOutputStream()); } public void link( String oldpath, String newpath ) { out.println(oldpath); out.println(newpath); out.flush(); } public void terminate() throws InterruptedException { out.close(); process.waitFor(); process.destroy(); } } – user2221529 Mar 30 '13 at 14:17
  • The first paragraph was very helpful (to know JNA uses the standard framework search-locations on MacOS to look for Frameworks). However - If I have a private Framework I do not want to expose to the public (by placing in one of these locations) what am I to do then? Can I not specify a custom predefined path? – Motti Shneor Feb 13 '22 at 17:53
  • You should be able to provide a complete, absolute path the the library you'd like to load. – technomage Feb 15 '22 at 17:43
0

Not really an answer, but more information on the same problem, which I'm experiencing myself.

I can add that JNA will find my frameworks if they're in one of the standard public locations an executable looks for its frameworks, i.e.

  • ~/Library/Frameworks - (public frameworks for the use of the current user)
  • /Library/Frameworks - (public frameworks for the use of any user)
  • /System/Library/Frameworks - (public system frameworks)

However, If I want my custom framework to be private - i.e. - not discoverable to other processes than my java vm -- then for some reason JNA doesn't do it.

I know MacOS dynamic loader, when trying to locate a library/framework for any normal (native) MacOS process, does NOT start searching the above locations, but first within several standard "private" locations: (also known as rpath search-path)

  • in the "Frameworks" directory at the same location as the binary from which the process was loaded: e.g. path/to/my/binary/Frameworks/mySDK.framework
  • in the "Frameworks" directory at the place where dynamic loader loaded the process (in Application bundles, that would be the myApp.app/Contents/Frameworks/mySDK.framework folder.

So, you can usually create a 'Frameworks' directory of your own right next to your binary, and place your framework in it.

However - JNA misses that. I tried to create a "Frameworks" directory within the "Zulu" - in zulu-11.jre/Contents/Home/bin right next to the 'java' binary, and in other places - but JNA won't find in any of them.

I wonder why, and if there is any documentation for that.

The trick of installing a symlink to my custom framework in /Library/Frameworks may serve you, but I cannot allow other processes to find or load my framework.

Motti Shneor
  • 2,095
  • 1
  • 18
  • 24