I need to call Windows Color System functions from Java. Following this tutorial i tried to call DLL function using Java Native Access. All examples from this tutorial works fine. When i try to load and use Mscms.dll (one of the WCS libraries) that DLL seems to be loaded successfully, but i can not call any functions. List of functions is here.
I got a message:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'GetColorDirectory'
What's wrong with my code? Could you help me please?
import com.sun.jna.Library;
import com.sun.jna.Native;
public class WCS_test {
public interface Mscms extends Library {
// http://msdn.microsoft.com/en-us/library/dd316928%28v=vs.85%29.aspx
boolean GetColorDirectory(String pMachineName, String[] pBuffer, int pdwSize);
}
private static Mscms mscms = (Mscms) Native.loadLibrary("C:/Windows/system32/Mscms.dll", Mscms.class);
public static void main(String[] args) {
if (mscms != null)
System.out.println("Library loaded\n");
else
System.err.println("Library loading error\n");
String[] pBuffer = new String[1024];
mscms.GetColorDirectory(null, pBuffer, pBuffer.length);
}
}
When you get a java.lang.UnsatisfiedLinkError that means that it could not find the function 'GetColorDirectory' inside of the Mscms.dll. Looking at the link from your source code http://msdn.microsoft.com/en-us/library/dd316928%28v=vs.85%29.aspx you should try the Unicode name GetColorDirectoryW.
Related
I want to wrap a C++ library (PCL) in Java code using JNI, but I am having inconsistent results. I have first created a PointXYZ class for testing and it looks like this:
package pcl;
public class PointXYZ extends NativeObject {
PointXYZ() { }
#Override
public native void alloc(); // creates pointer + handle on the native side
#Override
public native void dispose(); // sets handle to 0 and deletes pointer
public native float getX();
// ...
}
I have generated the C header for this class using javah, compiled everything using CMake, tested it using its getters and setters and everything works perfectly.
static {
System.setProperty("java.library.path", System.getProperty("user.dir") + "/lib");
System.loadLibrary("pcl_java_common");
}
#Test
void attributeAccessTest() {
PointXYZ p = new PointXYZ();
p.alloc();
p.setX(3);
assertEquals(p.getX(), 3);
p.dispose();
// all is good
}
Now I have done the exact same steps for a PointXYZRGB class which inherits from PointXYZ and when I try to test that it throws java.lang.UnsatisfiedLinkError. Here is the class:
package pcl;
public class PointXYZRGB extends PointXYZ {
public PointXYZRGB() { }
#Override
public native void alloc();
#Override
public native void dispose();
public native short getR();
// ...
}
I have checked the generated .dll using Dependency Walker and the PointXYZRGB methods are all present. Anyone knows what the problem could be?
UPDATE: Here are the .dll functions as requested in the comment:
The problem was that System.setProperty("java.library.path", System.getProperty("user.dir") + "/lib"); does not actually make Java look for .dll files in the given path. It essentially does nothing. Then why do the tests work for PointXYZ? This is was my mistake of having put an older .dll into the project root folder, so it was essentially looking for methods in that.
I want to use JNA to detect foreground application on Linux (Ubuntu 14). I followed this link
Find out what application (window) is in focus in Java
but I got the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'XLib': Native library (linux-x86-64/libXLib.so) not found in resource path ([file:/home/zzhou/workspace/home_prioritization_plus/bin/, file:/home/zzhou/Downloads/jna-4.1.0.jar, file:/home/zzhou/Downloads/jna-platform-4.1.0.jar])
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:271)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Library$Handler.<init>(Library.java:147)
at com.sun.jna.Native.loadLibrary(Native.java:412)
at com.sun.jna.Native.loadLibrary(Native.java:391)
at FunctionalityTest$XLib.<clinit>(FunctionalityTest.java:15)
at FunctionalityTest.main(FunctionalityTest.java:23)
The code is:
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
import com.sun.jna.platform.unix.X11;
import com.sun.jna.win32.StdCallLibrary;
public class FunctionalityTest {
static class Psapi {
static { Native.register("psapi"); }
public static native int GetModuleBaseNameW(Pointer hProcess, Pointer hmodule, char[] lpBaseName, int size);
}
public interface XLib extends StdCallLibrary {
XLib INSTANCE = (XLib) Native.loadLibrary("XLib", Psapi.class); // <-- PROBLEM
int XGetInputFocus(X11.Display display, X11.Window focus_return, Pointer revert_to_return);
}
public static void main(String args[]) {
if(Platform.isLinux()) { // Possibly most of the Unix systems will work here too, e.g. FreeBSD
final X11 x11 = X11.INSTANCE;
final XLib xlib= XLib.INSTANCE;
X11.Display display = x11.XOpenDisplay(null);
X11.Window window=new X11.Window();
xlib.XGetInputFocus(display, window,Pointer.NULL);
X11.XTextProperty name=new X11.XTextProperty();
x11.XGetWMName(display, window, name);
System.out.println(name.toString());
}
}
}
To import JNA library, I downloaded jna and jna-platform from https://github.com/twall/jna and use Configure Build Path... in Eclipse to add library. I did not install anything. May that be the source of the problem?
Thanks for your help.
Afaik, even for JNA, you have to load the library in Java in order for JNA to find it. (tested for win32, not linux)
Try this just above Native.loadLibrary:
System.loadLibrary("XLib");
I am new to accessing DLLs from Java using JNA. I need to access methods from a class within a DLL(written in .net). Form this sample DLL below, I am trying to get AuditID and Server ID. I am ending with the following error while I am running my code. Any guidance really appreciated.
/// Error ///
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'GetEnrollcontext': The specified procedure could not be found.
//DLL File Code//
SampleDLL.ProfileEnroll enrollcontext = new SampleDLL.ProfileEnroll();
enrollcontext.Url =” url”;
enrollcontext.AuditIdType = SampleDLL.ProfileId;
enrollcontext.AuditId = “22222222 “;
enrollcontext.ServerId = “server1”;
/// Java Code ///
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import dllExtract.DLLExtractTest.SampleDLL.Enrollcontext;
public class SampleDLLExtract {
public interface SampleDLL extends Library {
SampleDLL INSTANCE = (SampleDLL) Native.loadLibrary("SampleDLL",
SampleDLL.class);
public static class Enrollcontext extends Structure {
public String auditId;
public String serverId;
}
void GetEnrollcontext(Enrollcontext ec); // void ();
}
public static void main(String[] args) {
SampleDLL sdll = SampleDLL.INSTANCE;
SampleDLL.Enrollcontext enrollContext = new SampleDLL.Enrollcontext();
sdll.GetEnrollcontext(enrollContext);
System.out.println(sdll.toString(sdll.GetEnrollcontext(enrollContext)));
}
}
in fact there is a solution for you to use C#, VB.NET or F# code via JNA in Java (and nothing else)! and it is also very easy to use:
https://www.nuget.org/packages/UnmanagedExports
with this package all you need to do is, add [RGiesecke.DllExport.DllExport] to your methods like that:
C# .dll Project:
[RGiesecke.DllExport.DllExport]
public static String yourFunction(String yourParameter)
{
return "CSharp String";
}
Java Project:
public interface jna extends Library {
jna INSTANCE = (jna) Native.loadLibrary("yourCSharpProject.dll", jna.class);
public String yourFunction(String yourParameter);
}
use it in the code:
System.out.println(jna.INSTANCE.yourFunction("nothingImportant"));
Viola!
As already mentioned it works very easy, but this solution has some limitations:
only available for simple datatypes as parameter & return values
no MethodOverloading available. yourFunction(String yourParameter) and yourFunction(String yourParameter, String yourSecondParameter) does not work! you have to name them differently
Use arrays as parameter or return values. (JNA offers StringArray, but I am not able to use them in C#) (maybe there is a solution, but I couldn't come up with one so far!)
if you export a method you can't call it internally in your C# code (simple to bypass that by the following:
.
[RGiesecke.DllExport.DllExport]
public static Boolean externalAvailable(String yourParameter)
{
return yourInternalFunction(yourParameter);
}
With C# it works great, with VB.NET and F# I have no experience.
hope this helps!
I wrote this simple code:
public class Test {
public static void main(String args[]) {
OculusRift oculusRift = new OculusRift();
oculusRift.init();
HMDInfo hdmInfo = oculusRift.getHMDInfo();
System.out.println(hdmInfo);
// while(oculusRift.isInitialized()){
//
// }
oculusRift.destroy();
}
}
But I get this error
Exception in thread "main" java.lang.UnsatisfiedLinkError: de.fruitfly.ovr.OculusRift._initSubsystem()Z
at de.fruitfly.ovr.OculusRift._initSubsystem(Native Method)
at de.fruitfly.ovr.OculusRift.init(OculusRift.java:82)
at ec.test.test3.Test.main(Test.java:21)
Java Result: 1
I created and included a Library based on:
JRift-0.2.5.1.jar
JRiftLibrary-0.2.5.1.jar
JRiftLibrary-0.2.5.1-natives-windows.jar
From here
What is missing?
Edit:
Forced by extracting JRiftLibrary64.dll and adding its path explicitly to the java path
System.loadLibrary("JRiftLibrary64");
It works.. why does not work on the other way?
Have you tried JOVR? https://github.com/jherico/jovr
Here a complete example: https://github.com/jherico/jocular-examples
This library is simple, very solid and compatible with the current Oculus Runtime 1.8
Regards
I am using dll in java using JNA, but i am getting below error
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'GetStatus': The specified procedure could not be found.
Not getting how to resolve this issue?
Please help.
Here is java code
import com.sun.jna.Library;
import com.sun.jna.Native;
/** Simple example of native library declaration and usage. */
public class First {
public interface TEST extends Library {
public String GetStatus();
}
public static void main(String[] args) {
TEST obj = (TEST ) Native.loadLibrary("TEST ", TEST .class);
System.out.println( obj.GetStatus());
}
}
This Nugget is super easy to use and works perfectly. https://www.nuget.org/packages/UnmanagedExports
You need Visual Studio 2012 (express).
Once installed, just add [RGiesecke.DllExport.DllExport] before any static function you want to export. That's it!
Example:
C#
[RGiesecke.DllExport.DllExport]
public static int YourFunction(string data)
{
/*Your code here*/
return 1;
}
Java
Add the import at the top:
import com.sun.jna.Native;
Add the interface in your class. Its your C# function name preceded by the letter "I":
public interface IYourFunction extends com.sun.jna.Library
{
public int YourFunction(String tStr);
};
Call your DLL where you need it in your class:
IYourFunction iYourFunction = (IYourFunction )Native.loadLibrary("full or relative path to DLL withouth the .dll extention", IYourFunction.class);//call JNA
System.out.println("Returned: " + IYourFunction.YourFunction("some parameter"));
EDIT:
If the DLL is 32bit, the JDK/JRE has to be 32bit as well. Add the following check to your code:
if(!System.getProperty("os.arch").equals("x86")) {
throw new Exception(".NET DLL " + "32bits JRE/JDK is required. Currently using " + System.getProperty("os.arch") + ".\r\nTry changing your PATH environement variable.");
}