在编写C程序,然后调用Java代码,编译时遇到下面两个错:
1)undefined reference to `_JNI_CreateJavaVM’
2)cannot find -ljvm
下面说说解决方案,并为学习过程做个完整记录(我的开发环境是:Eclipse 和windows +minGW):
步骤一:新建一个C工程”CProjectDemo”,然后新建main.c
步骤三:新建一个准备被C访问的Java类”InvokeTestFromNative.java”
代码如下(在C:\Test):
public class InvokeTestFromNative{
public static void main(String[] args){
System.out.println(args[0]);
}
}
步骤三:编写main.c,代码如下:
#include "stdio.h"
#include "jni.h"
#include "string.h"
int main(void)
{
JavaVMOption options[1];
JNIEnv* env = NULL;
JavaVM* jvm = NULL;
JavaVMInitArgs vm_args;
long status;
jclass cls;
jmethodID mid;
//jfieldID fid;
jstring jstr;
jclass stringclass;
jobjectArray args;
//指定java的环境
options[0].optionString = "-Djava.class.path=.;C:\\Test";
memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 1;
vm_args.options = options;
//启动虚拟机
status = JNI_CreateJavaVM(&jvm, (void**)&env, (void*)&vm_args);
if(status != JNI_ERR)
{
//先获得class对象
cls = (*env)->FindClass(env, "InvokeTestFromNative");
if(cls != 0)
{
//获取方法ID,通过方法名和签名,调用静态方法
mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
if(mid != 0){
//生成字符串对象
const char* name = "hello world";
jstr = (*env)->NewStringUTF(env, name);
stringclass = (*env)->FindClass(env, "java/lang/String");
//生成String数组对象,以便传递给main方法
args = (*env)->NewObjectArray(env, 1, stringclass, jstr);
//调用main方法
(*env)->CallStaticVoidMethod(env, cls, mid, args);
}
}
//销毁Java虚拟机
(*jvm)->DestroyJavaVM(jvm);
return 0;
}else{
printf("JVM create fdiled!\n");
return -1;
}
}
这是一般会提示无法找到”jni.h“头文件等信息,需要设置jni开发库依赖文件。
步骤四:设置JNI开发的jni依赖环境(Eclipse工具设置)
首先,右击”CProjectDemo”,选择最下面的”Properties”选项,点击”C/C++ Build”选项。如下图所示:
此时在进行编译,会提示错误如下:”cannot find -ljvm“,是因为项目中并没有设置jvm的一些依赖环境,解决方法如下:
上图中的第4步的值是JDK安装目录下的lib目录
步骤五:编译运行
参考文章:
http://www.widecodes.com/0HzVUPkPge/jni-java-to-c-in-eclipse-undefined-reference-to-impjnicreatejavavm12.html
http://public0821.iteye.com/blog/423941
http://www.cnblogs.com/icejoywoo/archive/2012/02/24/2367116.html