[英]DLL Call From Java Returns an UnsatisfiedLinkError
Edit: Problem solved 编辑:问题解决了
I created a new project and imported the source files. 我创建了一个新项目并导入了源文件。 (After trying too many options the project configuration was wrong.) It seems that I had confused the load and loadlibrary functions.
(在尝试了太多选项之后,项目配置是错误的。)似乎我混淆了load和loadlibrary函数。 load requires an absolute path including file postfix, eg:
加载需要包含文件后缀的绝对路径,例如:
static { System.load("c:/windows/system32/jnpout32.dll");}
When trying to call jnpout32.dll ( http://www.hytherion.com/beattidp/comput/pport.htm ) from Java in Eclipse (Windows 7, Java SE1.7) I receive the error: 尝试在Eclipse(Windows 7,Java SE1.7)中从Java调用jnpout32.dll( http://www.hytherion.com/beattidp/comput/pport.htm )时收到错误消息:
Exception in thread "main" java.lang.UnsatisfiedLinkError: EEGTrigger.ioPort.Out32(SS)V
at EEGTrigger.ioPort.Out32(Native Method)
at EEGTrigger.pPort.setAllDataBits(pPort.java:53)
at EEGTrigger.pPort.<init>(pPort.java:19)
at EEGTrigger.EEGTrigger.main(EEGTrigger.java:11)
The dll file is located in System32, in the src folder, and in C:\\Users[user]\\AppData\\Local (as indicated by System.getenv()) 该dll文件位于System32,src文件夹和C:\\ Users [user] \\ AppData \\ Local(如System.getenv()所示)中
In the Classpath under User entries, the file is also loaded 在“类路径”中的“用户条目”下,该文件也已加载
jnpout32.dll - \[Project]\src\[Project]\
and it is visible under Referenced Libraries in the Package Explorer 它在“程序包资源管理器”中的“引用的库”下可见
Both these lines do not work: 这两条线都不起作用:
static { System.loadLibrary("jnpout32"); }
static { System.load("c:/windows/system32/jnpout32"); }
(.load as suggested in java.lang.UnsatisfiedLinkError - JNI ) (.load如java.lang.UnsatisfiedLinkError-JNI中所建议)
I have confirmed that (based on java.lang.UnsatisfiedLinkError ) 我已经确认(基于java.lang.UnsatisfiedLinkError )
System.getProperty("java.library.path")
returns the system32 path. 返回system32路径。
The complete code of the java project (I have only authored the EEGTrigger class. The rest comes with the dll.): Java项目的完整代码(我只编写了EEGTrigger类。其余的随dll一起提供。):
package EEGTrigger;
public class EEGTrigger {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Starting trigger...");
pPort lpt1 = new pPort();
testProtocol(lpt1);
}
private static void testProtocol(pPort lpt1) {
// TODO Auto-generated method stub
short selectTrigger = 0;
sendPulse(lpt1, selectTrigger);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
selectTrigger = 1;
sendPulse(lpt1, selectTrigger);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
selectTrigger = 2;
sendPulse(lpt1, selectTrigger);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
selectTrigger = 3;
sendPulse(lpt1, selectTrigger);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
selectTrigger = 4;
sendPulse(lpt1, selectTrigger);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
selectTrigger = 0;
sendPulse(lpt1, selectTrigger);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param lpt1
*/
public static void sendPulse(pPort lpt1, short selectTrigger) {
short trigger = 0;
short targetTrigger = 255;
short stimulusOnsetAsynchrony = 64;
short trialOnsetTrigger = 32;
short triggerOff = 0;
switch (selectTrigger) {
case 1 : trigger = targetTrigger;
break;
case 2 : trigger = stimulusOnsetAsynchrony;
break;
case 3 : trigger = trialOnsetTrigger;
break;
case 4 : trigger = triggerOff;
break;
default : trigger = triggerOff;
break;
}
lpt1.output(trigger);
try {
Thread.sleep(50); // 50 milliseconds
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lpt1.output(triggerOff);
}
}
package EEGTrigger;
/* Definitions in the build of jnpout32.dll are: */
/* short _stdcall Inp32(short PortAddress); */
/* void _stdcall Out32(short PortAddress, short data); */
public class ioPort
{
// declare native methods of 'jnpout32.dll'
// output a value to a specified port address
public native void Out32(short PortAddress, short data);
// input a value from a specified port address
public native short Inp32(short PortAddress);
// load 'jnpout32.dll'
static { System.loadLibrary("jnpout32");}
//static { System.load("c:/windows/system32/jnpout32"); }
}
package EEGTrigger;
// ** Derived from information provided on the web by Dr. Kenneth G. Schweller,
// ** ( http://web.bvu.edu/faculty/schweller/ ) and his Mars Rover project page.
public class pPort
{
ioPort pp; // wrapper class for 'Jnpout32.dll'
// with methods:
// int Out32(int port, int value);
// int Inp32(int port);
short portAddress; // address of data port
short currentVal; // current value of port bits
public pPort()
{
pp = new ioPort();
portAddress = (short)0x378; // Hex Address of Data Byte of PC Parallel Port
setAllDataBits((short)0); // initialize port bits to 0
currentVal = 0x00;
}
// wrap ParallelPort output method
public void output(short port, short value)
{
pp.Out32(port, value);
}
// wrap ParallelPort input method
public short input(short port)
{
return pp.Inp32(port);
}
// output to default Data port
public void output(short value)
{
pp.Out32(portAddress, value);
}
// input from default Data port
public short input()
{
return pp.Inp32(portAddress);
}
/**
* set all bits on Data port to zero
**/
public void setAllDataBits(short value)
{
pp.Out32(portAddress, value);
currentVal = value;
}
// For users who prefer dealing with Pin numbers
// Set Pin <pin> to <value>
public void setPin(short pin, short value)
{
if (pin >= 2 && pin <= 9)
// just set the corresponding Data bit to indicted value
setDataBit((short)(pin-2), value);
}
/**
* Set Data Bit at selected index to a value of 1 or 0
* while preserving current values of all other Data bits
**/
void setDataBit(short index, short value)
{
switch(index)
{
case 0:
if (value==0) // Set Data[0] to 0
currentVal = (short) (currentVal & 0xFE);
// aaaa aaaa currentVal
// AND 1111 1110 mask
// =========
// aaaa aaa0 new currentVal
else // Set Data[0] to 1
currentVal = (short) (currentVal | 0x01);
// aaaa aaaa currentVal
// OR 0000 0001 mask
// =========
// aaaa aaa1 new currentVal
break;
case 1:
if (value==0)
currentVal = (short) (currentVal & 0xFD);
// currentVal = aaaa aa0a
else
currentVal = (short) (currentVal | 0x02);
// currentVal = aaaa aa1a
break;
case 2:
if (value==0)
currentVal = (short) (currentVal & 0xFB);
// currentVal = aaaa a0aa
else
currentVal = (short) (currentVal | 0x04);
// currentVal = aaaa a1aa
break;
case 3:
if (value==1)
currentVal = (short) (currentVal & 0xF7);
// currentVal = aaaa 0aaa
else
currentVal = (short) (currentVal | 0x08); // currentVal = aaaa 1aaa
break;
case 4:
if (value==0)
currentVal = (short) (currentVal & 0xEF);
// currentVal = aaa0 aaaa
else
currentVal = (short) (currentVal | 0x10); // currentVal = aaa1 aaaa
break;
case 5:
if (value==0)
currentVal = (short) (currentVal & 0xDF);
// currentVal = aa0a aaaa
else
currentVal = (short) (currentVal | 0x20); // currentVal = aa1a aaaa
break;
case 6:
if (value==0)
currentVal = (short) (currentVal & 0xBF);
// currentVal = a0aa aaaa
else
currentVal = (short) (currentVal | 0x40); // currentVal = a1aa aaaa
break;
case 7:
if (value==0)
currentVal = (short) (currentVal & 0x7F);
// currentVal = 0aaa aaaa
else
currentVal = (short) (currentVal | 0x80); // currentVal = 1aaa aaaa
break;
default:
System.out.println("index must be 0 - 7");
}
pp.Out32(portAddress, currentVal);
}
}
The following questions were either not helpful or not applicable in this regard: 以下问题在这方面没有帮助或不适用:
java.lang.UnsatisfiedLinkError java.lang.UnsatisfiedLinkError
java.lang.UnsatisfiedLinkError java.lang.UnsatisfiedLinkError
java.lang.UnsatisfiedLinkError java.lang.UnsatisfiedLinkError
java.lang.UnsatisfiedLinkError java.lang.UnsatisfiedLinkError
java.lang.UnsatisfiedLinkError in Linux Linux中的java.lang.UnsatisfiedLinkError
Java.lang.UnsatisfiedLinkError in eclipse Eclipse中的Java.lang.UnsatisfiedLinkError
java.lang.UnsatisfiedLinkError: dbopen java.lang.UnsatisfiedLinkError:dbopen
JNI java.lang.UnsatisfiedLinkError JNI java.lang.UnsatisfiedLinkError
You haven't provided very much information about why you might be getting an UnsatisfiedLinkError. 您尚未提供有关为什么会收到UnsatisfiedLinkError的大量信息。 Try attaching the full stack trace.
尝试附加完整的堆栈跟踪。
System.loadLibrary("jnpout32") is correct as long as java.library.path is set when the JVM starts via java -Djava.library.path="%WINDIR%/system32/" 只要通过Java启动JVM时设置了java.library.path,System.loadLibrary(“ jnpout32”)都是正确的-Djava.library.path =“%WINDIR%/ system32 /”
If you want to use System.load, you should do something like System.load("c:/windows/system32/" + System.mapLibraryName("jnpout32")) to produce the native library name and extension. 如果要使用System.load,则应执行类似System.load(“ c:/ windows / system32 /” + System.mapLibraryName(“ jnpout32”))之类的操作来生成本机库名称和扩展名。
If you are using them properly and both continue to fail, your error is somewhere else like a dependent library that is missing. 如果您正确使用它们,并且两者都继续失败,那么您的错误就是在其他地方,例如缺少依赖库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.