You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用JNA调用C++时遇无法解析对应JNI函数错误的技术求助

解决JNA调用C++时的「Cannot resolve corresponding JNI function」错误

看起来你遇到的问题主要出在JNA方法映射的声明规范和库加载方式上,我帮你拆解问题并给出具体的修正方案:

问题根源

你的C代码是没问题的——用extern "C"包裹函数已经避免了C的名字修饰问题,这一步做对了。问题出在Java侧的JNA使用方式:你用Native.register加载了库,但没有完整声明对应的native方法签名,而且直接在Activity类上注册库并不是JNA推荐的用法,这导致JNA无法找到对应的JNI函数映射,从而抛出错误。

修正方案

1. 改用JNA推荐的接口映射方式

JNA更规范的做法是定义一个继承自Library的接口,在接口里声明对应的native方法,再通过Native.load加载库。这种方式不仅清晰,还能避免直接注册类带来的模糊匹配问题。

修改后的MainActivity代码如下:

package com.example.tenealaspencer.example;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.sun.jna.Library;
import com.sun.jna.Native;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 调用native方法获取库名称
        String libName = NativeLib.INSTANCE.libName();
        // 可根据需求使用返回值,比如打印到日志
        // Log.d("JNA", "Loaded Library: " + libName);
    }

    // 定义JNA接口,映射native方法
    public interface NativeLib extends Library {
        // 加载native库,JNA会自动处理lib前缀和.so后缀
        NativeLib INSTANCE = (NativeLib) Native.load("native-lib", NativeLib.class);
        
        // 对应C++中的char* libName(),JNA自动完成char*到Java String的转换
        String libName();
    }
}

2. 确认库文件路径和编译配置

  • 确保编译生成的libnative-lib.so文件放在正确目录:app/src/main/jniLibs/[你的CPU架构]/(比如armeabi-v7aarm64-v8a等)。
  • 如果用CMake编译,要保证CMakeLists.txt里的库名称设置为native-lib,示例如下:
add_library(
        native-lib
        SHARED
        native-lib.cpp)

3. 检查JNA依赖是否正确添加

app/build.gradle文件中,确认已添加JNA依赖(可使用最新版本):

dependencies {
    implementation 'net.java.dev.jna:jna:5.13.0'
}

为什么这样能解决问题?

  • 接口映射的方式让JNA明确知道要绑定的方法签名,避免了直接注册类时的匹配模糊问题。
  • JNA会自动处理Java与C++的类型转换(比如char*String),无需手动处理内存操作。

内容的提问来源于stack exchange,提问作者Yng Kody

火山引擎 最新活动