从C语言调用Java函数

时间:2016-02-23 09:08:18

标签: java c java-native-interface

我想从c代码调用java函数。 我使用了http://www.ishaanguliani.com/content/calling-java-functions-c-linux-ubuntu-jni

示例中讨论的JNI

我使用相同的代码并按照相同的步骤进行操作,但我无法找到类打印。

我调试但是我没找到我做错了。

在这里分享我的代码

unions@universe:~/uni_tmp/jni/vvn$ cat MyC.c 

#include <stdio.h>
#include <jni.h>
#include "MyJava.h"
#include <string.h>

JNIEnv* create_vm(JavaVM ** jvm) {
  JNIEnv *env;
  JavaVMInitArgs vm_args;
  JavaVMOption options;
  options.optionString = "-Djava.class.path=./"; //Path to the java     source code
  vm_args.version = JNI_VERSION_1_6; //JDK version. This indicates     version 1.6
  vm_args.nOptions = 1;
  vm_args.options = &options;
  vm_args.ignoreUnrecognized = 0;
  int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
  if(ret < 0)
    printf("\nUnable to Launch JVM\n"); 
  return env;
}

int main(void)
{
    JNIEnv *env;
    JavaVM *jvm;
    jmethodID mainMethod = NULL;
    jmethodID smfnMethod = NULL;
    jclass clsJava=NULL;
    jstring StringArg=NULL;

    env = create_vm(&jvm);
    if (env == NULL)
    {
       printf("\n Unable to create environment");
       return 1;
    }
    clsJava = (*env)->FindClass(env,"MyJava");
    if (clsJava != NULL)
    {
        printf("\n Able to find the requested class\n");  
    } else {
        printf("\n Unable to find the requested class\n");    
        return 0;   
    }
    mainMethod = (*env)->GetStaticMethodID(env, clsJava, "main", "    ([Ljava/lang/String;)V");

    smfnMethod = (*env)->GetStaticMethodID(env, clsJava,"sampleStaticFunc", "(Ljava/lang/String;)V");

    if (mainMethod != NULL)
    {
        printf("\n Calling the Java Main method");
        (*env)->CallStaticVoidMethod(env, clsJava, mainMethod, NULL);
    }
    StringArg = (*env)->NewStringUTF(env, "Argument from C");
    if (smfnMethod != NULL)
    {
        printf("\n Calling the Static Function method");
        (*env)->CallStaticVoidMethod(env, clsJava, smfnMethod,     StringArg);
    }
    printf("\n End C main \n");
    return 0;
}

Java代码

cat unions@universe:~/uni_tmp/jni/vvn$ cat MyJava.java 
public class MyJava 
{
  public MyJava()
  {
     System.out.println("\n Inside the constrcutor of Java Function \n "); 
  }
  private void sampleFunc(String str)
  {
     System.out.println("\n Inside sampleFunc value of string =  " + str); 
  }
  public static void sampleStaticFunc(String str)
  {
     System.out.println("\n Inside static sampleFunc value of string =      " + str); 
  }
  public static void main(String[] args)
  {
     MyJava obj = new MyJava();
     obj.sampleFunc("Ishaan is my name");
     System.out.println("\n Calling Java from C function \n"); 
  }
}

之后Ran这些命令

unions@universe:~/uni_tmp/jni/vvn$ javac MyJava.java 
unions@universe:~/uni_tmp/jni/vvn$ javah -jni MyJava

当我编译并且Ran我得到了这个输出

export LD_LIBRARY_PATH=/usr/lib/jvm/java-6-openjdk-amd64/jre/lib/amd64/server
unions@universe:~/uni_tmp/jni/vvn$ gcc -I /usr/lib/jvm/java-6-openjdk-amd64/include  -I /usr/lib/jvm/java-6-openjdk-amd64/include/linux -L /usr/bin/java -L /usr/lib/jvm/java-6-openjdk-amd64/jre/lib/amd64/server  MyC.c -ljvm ; ./a.out 

Unable to find the requested class

我做错了什么?

我将options.optionString更改为喜欢这个

options.optionString = "-Djava.class.path=/home/vpraveen/uni_tmp/jni/vvn";

即使输出没有变化。 有什么建议吗?

1 个答案:

答案 0 :(得分:1)

我通过将我的课程变成我自己的包来解决这个问题。 当我们没有定义任何包时,它将作为默认包。 所以我创建了自己的包,就像这样

package com.aqu.vvn

我知道这是一个解决方法,但这样做对我有用。 当我想出来时,我会让你知道确切的方法。