JNA调用自定义DLL遇UnsatisfiedLinkError:找不到hello函数
解决JNA调用自定义DLL时的UnsatisfiedLinkError问题
问题描述
使用JNA调用Visual Studio 2019编译的x64版本TestJNA.dll中的hello函数时,抛出java.lang.UnsatisfiedLinkError,提示找不到指定函数。尝试绝对路径加载DLL后问题依然存在。
核心原因
C++编译器会对函数名进行名字修饰(Name Mangling),在生成的DLL中,原函数名会被添加参数类型相关的前缀后缀,导致JNA无法通过原函数名hello匹配到实际函数。
解决方法
方法1:用extern "C"声明导出函数
修改C++代码,用extern "C"包裹需要导出的函数,强制编译器按照C语言规则生成函数名,避免名字修饰:
#include "pch.h" #include "TestJNA.h" #include<stdio.h> #include<string.h> #include<stdlib.h> // 用extern "C"包裹所有需要被JNA调用的函数 extern "C" { int hello() { printf("Hello world\n"); return 0; } int basicTest(int a, float b) { printf("a=%d\n", a); printf("b=%f\n", b); return (int)(a + b); } void arrayTest(char* pStr, unsigned char* puStr) { int i = 0; printf("%s\n", pStr); for (i = 0; i < 10; i++) { printf("%c ", puStr[i]); } } void pointerTest(int* pInt, float* pFloat) { *pInt = 10; *pFloat = 12.34; } void mallocTest(char* pszStr) { strcpy_s(pszStr, 50, "Happay Children's Day!"); } void doublePointTest(int** ppInt, char** ppStr) { printf("before int:%d\n", **ppInt); **ppInt = 10086; *ppStr = (char*)malloc(10 * sizeof(char)); strcpy_s(*ppStr, 50, "Happy National Day!"); } void freePoint(void* pt) { if (pt != NULL) { free(pt); } } } int main() { hello(); system("pause"); return 0; }
修改后重新编译DLL,再用JNA调用即可匹配到原函数名。
方法2:在JNA接口中指定修饰后的函数名
若不想修改C++代码,可先查看DLL中实际的函数名:
- 打开VS的x64 Native Tools Command Prompt for VS 2019
- 执行命令:
dumpbin /exports TestJNA.dll - 找到
hello对应的修饰后名称(例如?hello@@YAHXZ)
然后在JNA接口中用@Function注解指定该名称:
import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Function; public interface Clibrary extends Library { Clibrary INSTANCE = Native.load("TestJNA", Clibrary.class); @Function(name = "?hello@@YAHXZ") // 替换为dumpbin查到的实际名称 int hello(); // 其他函数需同理指定修饰后的名称 int basicTest(int a, float b, String pChar); void arrayTest(String pStr, byte[] puStr); void pointerTest(IntByReference pInt, FloatByReference pFloat); void mallocTest(Memory pString); void doublePointTest(PointerByReference ppInt, PointerByReference ppStr); void freePt(Pointer pt); }
额外检查项
- 确认DLL平台与JVM平台一致:用
System.getProperty("os.arch")查看JVM架构,必须和DLL的x64/32位匹配。 - 确认DLL路径正确:绝对路径加载时,文件名需正确(例如
TestJNA.dll或不带后缀的TestJNA)。 - 确认函数已正确导出:除
extern "C"外,也可通过VS的.def文件或__declspec(dllexport)显式标记导出函数。
内容的提问来源于stack exchange,提问作者HuaJFrame
相关产品推荐
相关产品推荐

