Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6318402
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: Java

2013-06-30 09:29:45

原文地址:c语言调用java类 作者:mfc42d

剑客一直说我写的blog属于阳春白雪,很少有人看懂,以后尽量向大家灌输一些基础知识。
c语言通过jvm环境可以调用java类,我以前的blog写过。http://blogger.org.cn/blog/more.asp?name=hongrui&id=25509
只是新的版本发生了一点变化,没有JDK1_1InitArgs的定义,详见bug,
不在需要调用JNI_GetDefaultJavaVMInitArgs。
先写java类,
import java.awt.*;
import java.awt.event.*;
public class MyApp2 extends Frame
{
    public MyApp2()
    {
        super( "My Java App" );
        add( new Label("Hello, world!") );
    }
    public static void main( String[] args )
    {
        MyApp2 frame = new MyApp2();
        frame.addWindowListener( new WindowAdapter()
        {
            public void windowClosing(WindowEvent e) {System.exit(0);}
        });
        frame.setSize(200,200);
        frame.setVisible(true);
    }
}

编译为jar后,运行java -cp ./app.jar MyApp2

调用的java的c程序
#include

#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else /* UNIX */
#define PATH_SEPARATOR ':'
#endif

#define USER_CLASSPATH "." /* where Prog.class is */

#define MAIN_CLASS  "MyApp2"
#pragma comment(lib,"jvm.lib")
int main()
{
    JNIEnv *env;
    JavaVM *jvm;
    jint res;
    jclass cls;
    jmethodID mid;
    jstring jstr;
    jobjectArray args;
    char classpath[1024];


    JavaVMInitArgs vm_args;
    JavaVMOption options[4];

    /* disable JIT */
    options[0].optionString = "-Djava.compiler=NONE";
    /* user classes */
    options[1].optionString = "-Djava.library.path=.";
    /*native library path*/
    options[2].optionString = "-Djava.class.path=D:\\idea\\gui\\out\\artifacts\\app\\app.jar";
    /* print JNI-related messages */
    //options[3].optionString = "-verbose:jni";
 options[3].optionString = "-verbose";
     vm_args.version = JNI_VERSION_1_6;
     vm_args.options = options;
     vm_args.nOptions = 4;
     vm_args.ignoreUnrecognized = JNI_TRUE;

     /* Note that in the Java 2 SDK, there is no longer any need to call
      * JNI_GetDefaultJavaVMInitArgs.
      */

    /* Append USER_CLASSPATH to the end of default system class path */
     /*      sprintf(classpath, "%s%c%s", */
     /*              vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); */
     /*      vm_args.classpath = classpath; */

    /* Create the Java VM */
     res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
     if (res < 0){
       fprintf(stderr,"ERROR creat JVM failed resultcode=%d\n",res);
       exit(1);D:\Java\jdk1.7.0_03\jre\bin\client
     }

    cls = (*env)->FindClass(env, MAIN_CLASS);
    if (cls == 0) {
        fprintf(stderr, "Can't find Prog class\n");
        exit(1);
    }
 
    mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
    if (mid == 0) {
        fprintf(stderr, "Can't find Prog.main\n");
        exit(1);
    }

    jstr = (*env)->NewStringUTF(env, " from C!");
    if (jstr == 0) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    args = (*env)->NewObjectArray(env, 1,
                        (*env)->FindClass(env, "java/lang/String"), jstr);
    if (args == 0) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    fprintf(stderr,"calling java...\n");
    (*env)->CallStaticVoidMethod(env, cls, mid, args);
    fprintf(stderr,"returned from java. killing VM.\n");

    (*jvm)->DestroyJavaVM(jvm);
}
然后把编译好的程序,放到D:\Java\jdk1.7.0_03\jre\bin\client目录下,只要是jvm.dll一个目录,然后运行就ok。
值得注意的是两个path:classpath 和 java.library.path
classpath是指向jar包的位置
java.library.path是非java类包的位置如(dll,so)
经常在LINUX下使用系统变量LD_LIBRARY_PATH来添加java.library.path
很少在vm arguments里添加-Djava.library.path= /usr/local/lib

阅读(1795) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~