【问题标题】:NoSuchMethodError with C++ method to Java Native InterfaceNoSuchMethodError 与 C++ 方法到 Java 本机接口
【发布时间】:2022-10-19 05:46:57
【问题描述】:

我正在创建一个 JNI 和 Java 类,以便我可以在 JVM 中使用 C++ 类。 但是,我遇到了一个问题,程序编译得很好,但在运行时,该方法是不可见的。 这是原始类中的C++

bool TraceLog::getLogs(std::vector<ByteArray> &vecLogs, unsigned int uiNumLines)
{
    bool bRet = VersionCheck::check(tServer, tError);

    unsigned int uiContId = 0;
    if (bRet)
        bRet = getChunk(uiContId, uiNumLines, vecLogs);

    while (bRet && uiContId > 0)
    {
        std::vector<ByteArray> vecChunk;
        bRet = getChunk(uiContId, uiNumLines, vecChunk);
        if (bRet)
            vecLogs.insert(vecLogs.end(), vecChunk.begin(), vecChunk.end());
    }

    return bRet;
}

这是我写的JNI

//fxcl.hsm.log.TraceLog.getLogs
extern "C"
JNIEXPORT void JNICALL Java_fxcl_hsm_log_TraceLog_getLogs
    (JNIEnv *ptEnv, jobject ptObj, jobject tVecLogs, jint tUiNumLines)
    {
     TraceLog& tLog=getDevice(*ptEnv, ptObj);
      std::vector<ByteArray> vecLogs;
      int uiNumLines=static_cast<unsigned int>(tUiNumLines);
      tLog.getLogs(vecLogs, uiNumLines);

      //convert to a vector of Java objects
      std::vector<jobject> vecJavaLogs;
      vecJavaLogs.reserve(vecLogs.size());
      for (auto iter = vecLogs.begin(); iter < vecLogs.end(); ++iter)
        vecJavaLogs.push_back(JniConvert::byteArray_uncast(*ptEnv, *iter));
      tVecLogs= JniObjectSet::toJava(*ptEnv, vecJavaLogs, "java/util/ArrayList");
    }

这是Java类中的方法

public native boolean getLogs(ArrayList<byte[]> vecLogs, int uiNumLines)
        throws ConnectionException;

有没有人遇到过这样的问题? 非常感谢帮助

【问题讨论】:

  • 您是否将 C++ 库加载到 JVM 中?
  • 是的,我做到了。我有一个生成文件,其中 .so 库指向该文件以进行编译和执行
  • 你有告诉JVM加载.so文件的Java代码吗?
  • 您尝试实现的本机方法的类名是什么?您评论中的类名与您的本机函数名称中的类名不一致。
  • 另请注意,分配给tVecLogs 是没有用的。

标签: java c++ java-native-interface nosuchmethoderror


【解决方案1】:

确保使用System.loadLibrary 加载您的库。

例子:

class TraceLog {
    static {
        System.loadLibrary("name");
    }

    public native boolean getLogs(ArrayList<byte[]> vecLogs, int uiNumLines)
        throws ConnectionException;
}

其中name 对应于您的本机库的名称。对于 libfoo.so,它将是 System.loadLibrary("foo");

如果您已经这样做,请发布整个异常消息。

【讨论】:

    猜你喜欢
    • 2011-02-12
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 2015-07-09
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多