2023-01-20 325
我正在使用Windows上的Eclipse制作一个简单的JNI测试应用程序.我的C ++编译器是MingW 4.6.2.当我尝试在测试DLL中调用功能时,Java将抛出UnsatisfiedLinkError(dll本身无问题加载).我已经验证了我的DLL导出一个” C”函数,其名称与javah实用程序生成的函数相同.
如何尝试 该功能可能会产生链接错误?(另外,是否有任何方法可以获取有关找不到哪些符号的详细信息”秃头”的秃头声明UnsatisfiedLinkError旁边是无用的.)
package com.xyz.jsdi_test;
import java.io.File;
public class JSDI
{
public static native void func(
String str,
int i,
Integer ii,
long j /* 64 bits */,
Long jj,
byte[] b
);
public static void dummy()
{
System.out.println("JSDI.dummy()");
}
static
{
File f = new File("..\\jsdi\\bin\\jsdi.dll");
System.out.println("Preparing to load: " + f);
System.load(f.getAbsolutePath());
System.out.println("Successfully loaded: " + f);
}
...
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_xyz_jsdi_test_JSDI
* Method: func
* Signature: (Ljava/lang/String;ILjava/lang/Integer;JLjava/lang/Long;[B)V
*/
JNIEXPORT void JNICALL Java_com_xyz_jsdi_1test_JSDI_func
(JNIEnv *, jclass, jstring, jint, jobject, jlong, jobject, jbyteArray);
#ifdef __cplusplus
}
#endif
extern "C"
{
JNIEXPORT void JNICALL Java_com_xyz_jsdi_1test_JSDI_func(
JNIEnv * env,
jclass _class,
jstring str,
jint i,
jobject ii,
jlong j,
jobject jj,
jbyteArray b
)
{
// don't do anything...let's just try to get called successfully...
}
} // extern "C"
...
public static void main(String[] args)
{
JSDI.dummy(); // cause class to load, which should cause System.load() to run.
JSDI.func("hello", 0, 0, 0L, 0L, (byte[])null);
}
Preparing to load: ..\jsdi\bin\jsdi.dll
Successfully loaded: ..\jsdi\bin\jsdi.dll
JSDI.dummy()
java.lang.UnsatisfiedLinkError: com.xyz.jsdi_test.JSDI.func(Ljava/lang/String;ILjava/lang/Integer;JLjava/lang/Long;[B)V
at com.xyz.jsdi_test.JSDI.func(Native Method)
at com.xyz.jsdi_test.SimpleTest.main(SimpleTest.java:24)
解决了 – wooo!
事实证明,MSVC对__stdcall函数的名称进行了强调.明格没有. Windows JVM显然期望” _”前缀.一旦我将’_’列入函数名称并使用mingw进行了重建,一切都奏效了.
eg :
JNIEXPORT void JNICALL Java_com_xyz_jsdi_1test_JSDI_func ==> _Java_com_xyz_jsdi_1test_JSDI_func
编辑:
MINGW包含的dlltool实用程序的–add-stdcall-underscore功能可以为您透明地解决此问题.将其设置在您的makefile中,您不必担心拥有不同编译器的实际源代码的不同版本.请参阅在此链接.
发布一个工作示例,在同一目录中的三个文件中复制内容(修改JDK的路径),然后调用build.cmd
/* File: HelloWorld.java */
public class HelloWorld {
private static native void writeHelloWorldToStdout();
public static void main(String[] args) {
System.loadLibrary("HelloWorld");
writeHelloWorldToStdout();
}
}
/* File: HelloWorld.c */
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_writeHelloWorldToStdout(JNIEnv *env, jclass c)
{
printf("Hello World!");
}
rem File: build.cmd
%echo off
echo delete generated binaries
del HelloWorld.class
del HelloWorld.dll
del HelloWorld.h
del HelloWorld.def
echo Compile the Java Class
javac HelloWorld.java
echo Generate the Header file
javah -classpath . -o HelloWorld.h HelloWorld
echo Build the DLL
gcc -I"C:\Program Files (x86)\Java\jdk1.7.0_25\include" -I"C:\Program Files (x86)\Java\jdk1.7.0_25\include\win32" -Wl,--add-stdcall-alias -Wl,--output-def,HelloWorld.def -shared -o HelloWorld.dll HelloWorld.c
echo run the program
java HelloWorld
例外中的签名没有” int”参数.因此,您的Java代码不同意您的本机代码.
以上所述是小编给大家介绍的为什么我在Windows上调用MinGW编译的函数(不加载库)时,会出现UnsatisfiedLinkError?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/25980.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态