android - 尝试从 libart.so 调用 JNI_CreateJavaVM 失败

标签 android c++ xamarin.android java-native-interface dlsym

我正在开发带有 C++ 部分的 Xamarin.Android 应用程序。现在我需要从 C++ 库中直接调用 Android Java 接口(interface)。

我从 Caleb Fenton's detailed and very helpful blog post 复制了代码使用 JNI 调用 从 C++ 到 Java .但是我无法像他那样获得指向 JVM 的指针。

(顺便说一句,我主要是一名 C# 程序员,所以我完全有可能在 C++ 中犯了一个基本错误)。

在头文件中:

 #pragma once
class MyJniClass
{
    //Create this once and cache it.
    JavaVM *m_jvm;                      // Pointer to the JVM (Java Virtual Machine)
    JNIEnv *m_env;                      // Pointer to native interface
    bool init_jvm();
}

在 .cpp 文件中:
    #include <jni.h>
#include <dlfcn.h>
#include "MyJniClass.h"

typedef int(*JNI_CreateJavaVM_t)(void *, void *, void *);


/**Code is based on https://github.com/rednaga/native-shim/blob/master/vm.c  
*/
bool MyJniClass::init_jvm() 
{
    // https://android.googlesource.com/platform/frameworks/native/+/ce3a0a5/services/surfaceflinger/DdmConnection.cpp
    JavaVMOption opt[1];
    opt[0].optionString = "-Djava.class.path=."; // I added a small java class to the dll to which this C++ class is linked, 
                                                 //so that there would be a java class in the current directory.  

    //opt/*[1]*/.optionString = "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";


    JavaVMInitArgs args;
    args.version = JNI_VERSION_1_6;
    args.options = opt;
    args.nOptions = 1;
    args.ignoreUnrecognized = JNI_FALSE;

    void *libart_dso = dlopen("libart.so", RTLD_NOW); //libdvm.so is outdated,  libnativehelper.so doesn't work

    if (!libart_dso ) 
    {
        //Execution doesn't pass through here 
        return false;
    }

    //Try to get the JNI_CreateJavaVM function pointer
    JNI_CreateJavaVM_t JNI_CreateJavaVM;
    JNI_CreateJavaVM = (JNI_CreateJavaVM_t)dlsym(libart_dso, "JNI_CreateJavaVM");
    if (!JNI_CreateJavaVM) 
    {
        //Execution doesn't pass through here 
        return false;
    }

    signed int result = JNI_CreateJavaVM(&(m_jvm), &(m_env), &args);

    if ( result != 0)
    {
        ostringstream os;
        os << "Call to JNI_CreateJavaVM returned ";
        os << result;
        m_logger->writeEntry(Loglevel::debug, os.str()); // ===> Here, I can see that result is always -1
        return false;
    }

    return true;
}

我试图在ART源代码here中找到函数JNI_CreateJavaVM ,但我找不到它。但它肯定应该在那里,以便 dlsym 可以找到该功能?我想我必须进一步寻找 libart.so 的源代码。

我做错了什么,我无法获得对 JNI_CreateJavaVM 的有效调用?

最佳答案

这里的第一个修改是添加诊断选项 Xcheck:jni .
这将在出现错误时提供详细信息。
通过修改 JavaVMOption opt[1]; 添加另一个选项至JavaVMOption opt[2];然后,添加以下选项:opt[1].optionString = "-Xcheck:jni" .

此外,dll 必须从它的原始位置加载(因为涉及其他 DLL),而不是从您的项目目录中加载。
Mor详细信息在以下帖子中提供:
JNI_CreateJavaVM() terminates with exit code 1

最后,您应该通过修改将指针转换为本地接口(interface) JNIEnv:

signed int result = JNI_CreateJavaVM(&(m_jvm), &(m_env), &args);


signed int result = JNI_CreateJavaVM(&(m_jvm), (void**)&(m_env), &args);

这应该可以解决问题。

关于android - 尝试从 libart.so 调用 JNI_CreateJavaVM 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56290184/

相关文章:

c# - 在哪里找到 ViewID

c# - Monodroid BitmapFactory.DecodeFileDescriptor 位图始终为 null

xamarin.ios - 使用 xamarin 的 Azure 移动服务 Blob 存储

java - Android 应用程序在某些手机上强制半重启/崩溃

android - MapFragment和CameraView(Surfaceview)下的Navigationdrawer

android - 致命异常 - 无法实例化 Activity - 真实应用程序类为空

c++ - Xcode C++ 和 Objective-C 重构

c++ - Lambda 语法或 gcc 错误的最后一刻更改?

c++ - 在 C/C++ 中从 main() 返回值的目的是什么?

java - 计算android中的时差