gpt4 book ai didi

java - 为什么在 Windows 上调用 MinGW 编译的函数(不加载库)时出现 UnsatisfiedLinkError?

转载 作者:可可西里 更新时间:2023-11-01 14:04:27 26 4
gpt4 key购买 nike

我正在 Windows 上使用 Eclipse 制作一个简单的 JNI 测试应用程序。我的 C++ 编译器是 MinGW 4.6.2。当我尝试在我的测试 DLL 中调用一个函数时,Java 抛出一个 UnsatisfiedLinkError(DLL 本身加载没有问题)。我已验证我的 DLL 导出了一个与 javah 实用程序生成的函数同名的“C”函数。

尝试调用该函数怎么可能会产生链接错误?(此外,是否有任何方法可以获取有关未找到的符号的更多详细信息? 存在 UnsatisfiedLinkError 的空头声明几乎毫无用处。)

这是定义 native 函数的 Java:

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);
}

这是 javah 的相应输出:

...
#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)

最佳答案

解决了——哇哦!

事实证明,MSVC 在 __stdcall 函数的名称前添加了一个下划线。 MinGW 没有。 Windows JVM 显然需要“_”前缀。一旦我在函数名称前加上“_”并使用 MinGW 重新构建,一切都运行得很好。

例如:

JNIEXPORT void JNICALL Java_com_xyz_jsdi_1test_JSDI_func ==> _Java_com_xyz_jsdi_1test_JSDI_func

编辑:MinGW 随附的 dlltool 实用程序的 --add-stdcall-underscore 功能可以透明地为您解决此问题。在您的 Makefile 中设置它,您无需担心不同编译器的实际源代码版本不同。参见 at this link .

关于java - 为什么在 Windows 上调用 MinGW 编译的函数(不加载库)时出现 UnsatisfiedLinkError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17199904/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com