我正在尝试使用C文件调用Java类中的方法。我正在使用JNI。这是调用java类中方法的ms .C文件:
#include <stdio.h>
#include<jni.h>
JNIEnv* create_vm(JavaVM **jvm)
{
JNIEnv* env;
JavaVMInitArgs args;
JavaVMOption options;
args.version = JNI_VERSION_1_6;
args.nOptions = 1;
options.optionString = "-Djava.class.path=./";
args.options = &options;
args.ignoreUnrecognized = 0;
int rv;
rv = JNI_CreateJavaVM(&jvm, (void**)&env, &args);
if (rv < 0 || !env)
printf("Unable to Launch JVM %d\n",rv);
else
printf("Launched JVM! :)\n");
return env;
}
void invoke_class(JNIEnv* env)
{
jclass hello_world_class;
jmethodID square_method;
jint number=20;
hello_world_class = (*env)->FindClass(env, "MainActivity");
square_method = (*env)->GetStaticMethodID(env, hello_world_class, "square", "(I)I");
printf("%d squared is %d\n", number,
(*env)->CallStaticIntMethod(env, hello_world_class, square_method, number));
}
int main(int argc, char **argv)
{
JavaVM *jvm;
JNIEnv *env;
env = create_vm(&jvm);
if(env == NULL)
return 1;
invoke_class(env);
return 0;
}
当我尝试构建项目时,它不断给我一个错误
C:\项目\ AndroidProjects \ NDKSample \应用\ SRC \主\ JNI \ test.c的 错误:(16)对JNI_CreateJavaVM&#39;未定义的引用错误:错误:ld 返回1退出状态make.exe:*** [C:/Projects/AndroidProjects/NDKSample/app/src/main/obj/local/armeabi/libMyLib.so] 错误1 make.exe:离开目录 `C:/项目/ AndroidProjects / NDKSample /应用程序/ SRC /主/ JNI&#39; :应用:ndkBuild FAILED错误:任务执行失败&#39;:app:ndkBuild&#39;。
处理&#39;命令&#39; C:\ Users \ mmjoshi \ AppData \ Local \ Android \ ndk \ ndk-build.cmd&#39;&#39;完 具有非零退出值2
请告诉我,我该如何解决此错误? 请注意,我在Windows 7的Android Studio中尝试此操作。
以下是我的Graddle文件,仅供参考:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "einfo.ndksample"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
ndk {
moduleName "MyLib"
}
}
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
jni.srcDirs = [] //disable automatic ndk-build call
}
project.ext.versionCodes = ['armeabi':1, 'armeabi-v7a':2, 'arm64-v8a':3, 'mips':5, 'mips64':6, 'x86':8, 'x86_64':9] //versionCode digit for each supported ABI, with 64bit>32bit and x86>armeabi-*
android.applicationVariants.all { variant ->
// assign different version code for each output
variant.outputs.each { output ->
output.versionCodeOverride =
project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + defaultConfig.versionCode
}
}
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
def ndkDir = android.ndkDirectory.getAbsolutePath()
commandLine ndkDir + '\\' + 'ndk-build.cmd', '-C', file('src/main/jni').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main/jni').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
}
提前致谢!
答案 0 :(得分:1)
在Android上,您无法从C创建Java VM。但是没有必要这样做:您的应用程序已经在JVM中运行,并且您的本机代码不需要int main()
入口点。相反,它被编译成共享库(DLL的Android模拟),并从Java加载(通常来自具有本机方法的类的静态构造函数)。
Android支持从C到Java的调用(通过FindClass和CallStaticMethod及其亲属),但在来自Java的调用中收到JNIEnv* env
,而不是在C中创建。