You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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中实际的函数名:

  1. 打开VS的x64 Native Tools Command Prompt for VS 2019
  2. 执行命令:dumpbin /exports TestJNA.dll
  3. 找到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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:40:59