Comments (18)
Hello I will try to get one Windows PC this week to taste on Windows, currently I just have a Mac to support the library.
from simpleopenni.
I wouldn't worry about Windows support yet--this is a bug that's been in every version of SimpleOpenNI since the beginning. If you can fix the Mac side, I can test on other OSes. Could you add the source of the SimpleOpenNI library itself? Like:
https://github.com/jaegonlee/SimpleOpenNI/tree/master/src/SimpleOpenNI
from simpleopenni.
I try this library for Processing 3.3.7 on Windows10. It goes well. However, export problem does not fix yet. Would you please fix nativLibPath in simpleOpenNI.java. It is explained in wexstorm/simple-openni#73 .
from simpleopenni.
OK, I think I have a solution--it needed a few changes from the wexstorm one. Sent a PR for 3.4.
https://github.com/n1ckfg/SimpleOpenNI/blob/Processing_3.4/SimpleOpenNI/src/SimpleOpenNI/SimpleOpenNI.java#L32
from simpleopenni.
Unfortunately the fix worked for depth but not for NITE--seems like NITE looks in the user's home directory (for some reason) when exported as a library regardless of the path set in the main jar.
from simpleopenni.
Eek – just ran into this issue... it's not quite clear if it's been fixed or what one needs to do?
(my setup is Processing 3.4, MacOS 10.9.5, hoping to run app on MacOS 10.13.6 high sierra)
from simpleopenni.
Oh hey, big fan of XYscope. So I've researched this quite a bit, even experimented with recompiling the jar, and my conclusion is it's a path issue with NITE, which we don't have the source for, so it can't be completely fixed. (Hope I'm wrong though.) The good news is, there's a workaround: place the SimpleOpenNI library folder at the root of your boot drive, and all exported apps can find it. This makes it really hard for distribution to civilians, but otherwise it's not even that bad a solution, because you don't need the same 200MB folder for every app. Further good news is it still works up to Win10 and High Sierra. (Haven't tried Mojave.)
from simpleopenni.
Thaanks + super thanks for quick reply. Ahaa, I was wondering about this when seeing what was changed in your various commits.. yup yup worked great (indeed not sooo user-friendly) but better than a sad gray-screen of nothingness.
Is there a flag or snippet to prevent it from including the 200mb library one each export, or simply have to inspect package contents and trash it?
If using skeleton tracking, does one still need to install OpenNi2:
brew tap brewsci/science
brew install openni2
My setup already has it.. so hard to test if app runs on fresh machine..
from simpleopenni.
I just trash it...don't believe it's necessary to install OpenNI separately but need to test. Fwiw I always install the SenseCast version of OpenNI 1 on a new machine as a good-luck ritual.
from simpleopenni.
Aha, nice tip (will check if OpenNI 1 suites my needs)– thanks again.
from simpleopenni.
I don't know if it helps here, but I think NiTE's decision about where to load things from has to do with the current working directoy when you load it. I've recently developed a plugin for Isadora that uses NiTE. To get that to work I had to determine the path the the dylib and then use the chdir() command to set the working directory. My code for this is below.
`
#import <dlfcn.h>
#import <mach-o/dyld.h>
#import <mach-o/nlist.h>
#import <stdio.h>
#import <string.h>
#ifdef __LP64__
typedef struct mach_header_64 mach_header_t;
typedef struct segment_command_64 segment_command_t;
typedef struct nlist_64 nlist_t;
#else
typedef struct mach_header mach_header_t;
typedef struct segment_command segment_command_t;
typedef struct nlist nlist_t;
#endif
static const char * first_external_symbol_for_image(const mach_header_t *header)
{
Dl_info info;
if (dladdr(header, &info) == 0)
return NULL;
segment_command_t *seg_linkedit = NULL;
segment_command_t *seg_text = NULL;
struct symtab_command *symtab = NULL;
struct load_command *cmd = (struct load_command *)((intptr_t)header + sizeof(mach_header_t));
for (uint32_t i = 0; i < header->ncmds; i++, cmd = (struct load_command *)((intptr_t)cmd + cmd->cmdsize))
{
switch(cmd->cmd)
{
case LC_SEGMENT:
case LC_SEGMENT_64:
if (!strcmp(((segment_command_t *)cmd)->segname, SEG_TEXT))
seg_text = (segment_command_t *)cmd;
else if (!strcmp(((segment_command_t *)cmd)->segname, SEG_LINKEDIT))
seg_linkedit = (segment_command_t *)cmd;
break;
case LC_SYMTAB:
symtab = (struct symtab_command *)cmd;
break;
}
}
if ((seg_text == NULL) || (seg_linkedit == NULL) || (symtab == NULL))
return NULL;
intptr_t file_slide = ((intptr_t)seg_linkedit->vmaddr - (intptr_t)seg_text->vmaddr) - seg_linkedit->fileoff;
intptr_t strings = (intptr_t)header + (symtab->stroff + file_slide);
nlist_t *sym = (nlist_t *)((intptr_t)header + (symtab->symoff + file_slide));
for (uint32_t i = 0; i < symtab->nsyms; i++, sym++)
{
if ((sym->n_type & N_EXT) != N_EXT || !sym->n_value)
continue;
return (const char *)strings + sym->n_un.n_strx;
}
return NULL;
}
const char * pathname_for_handle(void *handle)
{
for (int32_t i = _dyld_image_count(); i >= 0 ; i--)
{
const char *first_symbol = first_external_symbol_for_image((const mach_header_t *)_dyld_get_image_header(i));
if (first_symbol && strlen(first_symbol) > 1)
{
handle = (void *)((intptr_t)handle | 1); // in order to trigger findExportedSymbol instead of findExportedSymbolInImageOrDependentImages. See `dlsym` implementation at http://opensource.apple.com/source/dyld/dyld-239.3/src/dyldAPIs.cpp
first_symbol++; // in order to remove the leading underscore
void *address = dlsym(handle, first_symbol);
Dl_info info;
if (dladdr(address, &info))
return info.dli_fname;
}
}
return NULL;
}
void
SetWorkingDirectoryToNiteLibraryPath()
{
void* lib_handle = dlopen("libNite2.dylib", RTLD_LOCAL| RTLD_LAZY);
if (lib_handle != NULL) {
std::string path = pathname_for_handle(lib_handle);
if (path.length() > 1) {
size_t pos = path.rfind("/");
if (pos >= 1) {
path = path.substr(0, pos);
int result = chdir(path.c_str());
int debug_breakpopint = result;
}
}
}
}
`
Hopefully that might help you address the problem.
Also, I had to muck about with @loader_path to so that everytthing would work properly, but maybe that doesn't apply to you.
Best Wishses,
Mark
from simpleopenni.
Whoa, this is the first solid lead I think we've had in the several years this issue has been hanging around. Thanks!
from simpleopenni.
I've done some research about this problem today. Below are what I have found out:
the error info is:
Can't load SimpleOpenNI library (libSimpleOpenNI.jnilib) : java.lang.UnsatisfiedLinkError: Can't load library: /SimpleOpenNI/library/libSimpleOpenNI.jnilib
Verify if you installed SimpleOpenNI correctly.
http://code.google.com/p/simple-openni/wiki/Installation
java.lang.UnsatisfiedLinkError: SimpleOpenNI.SimpleOpenNIJNI.swig_module_init()V
at SimpleOpenNI.SimpleOpenNIJNI.swig_module_init(Native Method)
at SimpleOpenNI.SimpleOpenNIJNI.<clinit>(SimpleOpenNIJNI.java:290)
at SimpleOpenNI.ContextWrapper.<init>(ContextWrapper.java:54)
at SimpleOpenNI.SimpleOpenNI.<init>(SimpleOpenNI.java:253)
at Sketch.settings(Sketch.java:28)
at processing.core.PApplet.handleSettings(PApplet.java:954)
at processing.core.PApplet.runSketch(PApplet.java:10786)
at processing.core.PApplet.main(PApplet.java:10511)
at Main.main(Main.java:7)
Why this happend?
Open SimpleOpenNI.jar
through IntelliJ, and view SimpleOpenNI.class
, below are how libSimpleOpenNI.jnilib
is loaded:
static {
String var0 = System.getProperty("os.name").toLowerCase();
String var1 = "SimpleOpenNI";
String var2 = System.getProperty("os.arch").toLowerCase();
if (var0.indexOf("win") >= 0) {
// ...
} else if (var0.indexOf("nix") < 0 && var0.indexOf("linux") < 0) {
if (var0.indexOf("mac") >= 0) {
var1 = "lib" + var1 + ".jnilib";
nativLibPath = getLibraryPathLinux() + "/SimpleOpenNI/library/";
nativDepLibPath = nativLibPath + "osx/";
}
} else {
nativLibPath = "/SimpleOpenNI/library/linux";
if (var2.indexOf("86") >= 0) {
var1 = var1 + "32";
} else if (var2.indexOf("64") >= 0) {
var1 = "lib" + var1 + "64.so";
nativLibPath = getLibraryPathLinux() + "/SimpleOpenNI/library/";
nativDepLibPath = nativLibPath + "linux64/";
}
}
try {
System.load(nativLibPath + var1);
} catch (UnsatisfiedLinkError var5) {
System.out.println("Can't load SimpleOpenNI library (" + var1 + ") : " + var5);
System.out.println("Verify if you installed SimpleOpenNI correctly.\nhttp://code.google.com/p/simple-openni/wiki/Installation");
}
_initFlag = false;
}
notice that, the result of getLibraryPathLinux()
should be added before /SimpleOpenNI/library/libSimpleOpenNI.jnilib
, the string appeared in the error information. Let's look at the function:
public static String getLibraryPathLinux() {
URL var0 = SimpleOpenNI.class.getResource("SimpleOpenNI.class");
if (var0 != null) {
String var1 = var0.toString().replace("%20", " ");
int var2 = var1.indexOf(47);
boolean var3 = true;
int var4 = var1.indexOf("/SimpleOpenNI/library");
return -1 < var2 && -1 < var4 ? var1.substring(var2, var4) : "";
} else {
return "";
}
}
···
Notice this line
```java
int var4 = var1.indexOf("/SimpleOpenNI/library");
SimpleOpenNI tries to find substring /SimpleOpenNI/library
from the full path of SimpleOpenNI.class
file. If the substring does not show up, this function return an empty string. This is why processing fails to load SimpleOpenNI.jnilib file in exported application: when running from processing ide, the SimpleOpenNI.jar in ~/Documents/Processing/libraries/SimpleOpenNI/library
directory is used, the full path of which contains /SimpleOpenNI/library
. On the other hand, when running from exported application, the SimpleOpenNI.jar embedded in the application is used, which does not contain the required substring.
How to solve it.
A new implementation of getLibraryPathLinux
is required to fix this problem thoroughly. A temporary solution is given below:
- cd into your exported application bundle, go to
Contents/MacOS
, there should be a executable file with the same name of your exported application,Sketch
, for example. Remove this file, and create a new empty file with the same name, edit the file and add the following contents:
#!/bin/bash
cd "$(dirname ${BASH_SOURCE})"
cd ../..
APP_ROOT=$(pwd)
cd Contents/Java
JAR_LIBS=$(ls *.jar | tr "\n" ":")
JAR_LIBS=${JAR_LIBS}./SimpleOpenNI/library/SimpleOpenNI.jar
APP_NAME=$(basename "${BASH_SOURCE}")
# Caution: if your embedded java has a different version, replace jdk1.8.0_181.jdk with the correct name
# if you didn't choose to embedded java in your exported application, set JAVA_BIN=java to use the global java
JAVA_BIN=${APP_ROOT}/Contents/PlugIns/jdk1.8.0_181.jdk/Contents/Home/jre/bin/java
${JAVA_BIN} \
-Djna.nosys=true \
-Djava.ext.dirs=$APP_ROOT/Contents/PlugIns/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext \
-Xdock:icon=$APP_ROOT/Contents/Resources/sketch.icns \
-Djava.library.path=$APP_ROOT/Contents/Java \
-Dapple.laf.useScreenMenuBar=true \
-Dcom.apple.macos.use-file-dialog-packages=true \
-Dcom.apple.macos.useScreenMenuBar=true \
-Dcom.apple.mrj.application.apple.menu.about.name=${APP_NAME} \
-classpath ${JAR_LIBS} ${APP_NAME}
make this file executable
chmod +x ./Sketch
- Copy the entire folder
~/Documents/Processing/libraries/SimpleOpenNI
toContents/Java
.
from simpleopenni.
Amazing! I actually saved the jar source with my fork: https://github.com/n1ckfg/SimpleOpenNI/tree/Processing_3.4_test/SimpleOpenNI/src ...tried a couple path fixes and recompiled but no luck. Do you have an idea of how you would implement that directly in the source?
from simpleopenni.
Amazing! I actually saved the jar source with my fork: https://github.com/n1ckfg/SimpleOpenNI/tree/Processing_3.4_test/SimpleOpenNI/src ...tried a couple path fixes and recompiled but no luck. Do you have an idea of how you would implement that directly in the source?
FINALLY! Thanks to your fork I was able to apply a definitive fix for the infamous path bug in .exe files. With your build.bat file and small changes to the solution posted in this link, you can easily generate a brand new .jar file which works perfectly with standalone .exe files. Here´s how (requires Processing 3.4 + SimpleOpenNI-Processing_3.4):
-
Edit @n1ckfg ´s fork "SimpleOpenNI-Processing_3.4_test\SimpleOpenNI\src\SimpleOpenNI\SimpleOpenNI.java" file with any text editor.
-
Insert this code before line 32:
static String workingDir = System.getProperty("user.dir"); -
Replace lines 50 and 56 with:
nativLibPath = getLibraryPathWin() + workingDir + "/SimpleOpenNI/library/"; -
(optional) Edit @n1ckfg ´s .bat file and replace the "core.jar" location with the one at your current Processing library path if it´s not the same (as in my case). Save file changes if required.
-
Launch build.bat file, which generates the new SimpleOpenNI.jar
-
Overwrite the current file at export folder "\application.windows64\lib" with the new one.
-
Manually copy the folder SimpleOpenNI to the same folder where your .exe is located. (the one that contains subfolders: "documentation", "examples" and "library").
-
Launch the .exe file and this time it will load the SimpleOpenNI library and run the Kinect. Et voilà!
This should do the trick. Thanks again!
from simpleopenni.
Amazing!
from simpleopenni.
@totovr If we put this solution in a pull request, which branch would you like us to work in?
from simpleopenni.
Both OS X and Windows solutions tested and working.
from simpleopenni.
Related Issues (20)
- v2.2 crashes on mac mini every once a while (JRE fatal error; EXC_BAD_ACCESS)
- OSX High Sierra: Can't open device: no devices found HOT 5
- Question: Getting Rotation of Joints HOT 1
- Error opening database/parameters file MacOS Mojave HOT 2
- Anyone could get it working on Windows 10 HOT 2
- Delay on Lost User Programming Question
- Skipping Kinect v2 device
- Could anyone got it working on Linux/Ubuntu? HOT 5
- Blank Screen with no error
- On Ubuntu 18.04 JavaError: java.lang.UnsatisfiedLinkError
- Do not recognize SimpleOpenNI in Processing 3.5.4 Windows HOT 3
- How to setup Kinect Version 1 with Processing 3.5.4 on OSX 10.9.5 HOT 14
- Installation Error: Missing Library in Linux Release
- [Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out HOT 1
- Fixed: SimpleOpenNi stops working if RGB is enabled and depthness is too close
- Unable to successfully install SimpleOpenNI HOT 2
- Can i use latest raspberry pi processing software?
- Can't Open Device Processing 3.5.4 HOT 2
- multiple kinects v1? HOT 1
- [Processing 4] can not open device. no devices found
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from simpleopenni.