【发布时间】:2019-10-10 21:52:26
【问题描述】:
我正在开发带有 C++ 部分的 Xamarin.Android 应用程序。现在我需要从 C++ 库中直接调用 Android Java 接口。
我从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 的有效调用?
【问题讨论】:
-
您为什么不直接保存传递给
JNI_OnLoad的JavaVM*并继续使用它?我不明白您为什么需要尝试创建 JVM。 -
@Michael 因为它是一个 Xamarin 应用程序,所以 C++ 库永远不会从 Java 加载,JNI_OnLoad 处理程序永远不会运行。
-
我通过另一种策略解决了这个问题,没有使用JNI_CreateJavaVM或上面的代码。
标签: android c++ xamarin.android java-native-interface dlsym