• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

罗裳轻解,看C++怎样拥java入怀……

武飞扬头像
autumn
帮助1

// callJava.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>  
#include <cassert> //assert需要  
  
#include <jni.h> //jdk 的头文件  
  
using namespace std;  
  
struct JVMInfo  
{  
    JavaVM* jvm;  
    JNIEnv* env;  
      
    JavaVMInitArgs vm_args;  
      
    #define VM_OPT_COUNT 3  
    JavaVMOption options[VM_OPT_COUNT];  
      
    JVMInfo()  
        : jvm(0), env(0)  
    {  
        options[0].optionString = const_cast<char *>("-Djava.compiler=NONE");  
          
        //classpath有多个时,用";"分隔,UNIX下以":"分割。    
        options[1].optionString = const_cast<char *>("-Djava.class.path=.;C:\\Program Files\\Java\\jdk1.6.0_31\\lib\\dt.jar;C:\\Program Files\\Java\\jdk1.6.0_31\\lib\\tools.jar"); //这里,至少要包含前面java代码编译出来的Greeting.class文件所在路径  
                    //根据我设置的相对路径,可以推出我的callJava 的C  工程和demo的Java工程所在位置的相对关系。  
  
         //用于跟踪运行时的信息    
        options[2].optionString = const_cast<char *>("-verbose:none"); //"-verbose:jni" 换成这个,则jvm启动时,不会在屏幕上输出一堆信息  
          
        //JNI版本号  
        vm_args.version = JNI_VERSION_1_6;    
        vm_args.nOptions = VM_OPT_COUNT;    
        vm_args.options = options;    
        vm_args.ignoreUnrecognized = JNI_TRUE;                    
    }  
      
    //创建VM  
    bool Create()  
    {  
        assert(NULL == jvm && NULL == env);  
          
        //初始化虚拟机    
        return 0 == JNI_CreateJavaVM(&jvm, (void**)(&env), &vm_args);    
    }  
      
    //释放掉VM  
    void Destroy()  
    {  
        if (jvm)  
        {  
            jvm->DestroyJavaVM();  
              
            jvm = 0;  
            env = 0;  
        }  
    }  
      
    //一个演示功能  
    void Demo()  
    {  
        assert(NULL != jvm);  
      
        do  
        {  
            jclass cls = env->FindClass("Greeting");  
              
            #define BREAK_ON_FAIL(fail_condition, fail_msg)  if (fail_condition){ cerr << fail_msg << endl; break; }   
              
            BREAK_ON_FAIL(!cls, "Can't found class 'Greeting'!");  
              
            //找Greeting类的构造函数  
            jmethodID ctor = env->GetMethodID(cls, "<init>", "()V");  
  
            BREAK_ON_FAIL(!ctor, "Can't found class' ctor !");  
              
            //构建一个Greeting的对象  
            jobject obj = env->NewObject(cls, ctor);  
  
            BREAK_ON_FAIL(!obj, "Can't create a object of 'Greeting'!");  
              
            //找SayHello函数  
            jmethodID midOfSayHello = env->GetMethodID(cls, "SayHello", "()V");  
              
            BREAK_ON_FAIL(!midOfSayHello, "Can't found class' method 'SayHello()'!");  
                  
            //调用obj 的 SayHello 函数  
            env->CallObjectMethod(obj, midOfSayHello);  
        }while(false);  
    }      
};  
  
int main()  
{          
    JVMInfo jvmInfo;  
      
    if (!jvmInfo.Create())  
    {  
        cerr << "Create JVM fail!" << endl;  
        return -1;  
    }  
     
    cout << "C          " << endl;  
     
    jvmInfo.Demo();  
    jvmInfo.Destroy();  
      
    cout << "C          " << endl;   
  
    return 0;  
}  
/*
int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}
*/
public class Greeting {  

	public void SayHello() {  
		System.out.print("--------Hello C  , I'm Java.----------\n");  
	}  

	public static void main(String[] args)
	{
	  new Greeting().SayHello();
	}

}

罗裳轻解,看C 怎样拥java入怀……

java c jvm python 语言 jdk

前言

在公司里维护一个网络后台服务端程序,用C 写的,为了一些灵活性,就想集成个脚本语言,因为lua似乎没有什么库(或者是我对它比较无知),于是就选了老牌的python。确实噢,这家伙基本什么c/c 的库,都有它的封装。于是在服务端程序里,嵌了一个python的解释器。

可惜事情没有这么美好,公司里会python本来就不多,并且多数仅在入门。

让学Java的人去学习python? 有木有发现一个现象:学java的程序员们相对都比较自我封闭,基本都不爱再学门语言什么的,爱稳定,不爱折腾(凡客体?)

好吧,我知道java不是脚本语言,但反正它编译成class之后,也是交给c/c 的程序去执行的,这么一讲,它和php,python也差不多,可以当成需要伪编译一下脚本语言来看了——呀,我知道python也可以交给net平台或jvm上运行的,s可是这两个家伙不是C写的程序吗? (最近我写一句话:世界上只有两种语言,第一种是C语言,第二种是由C语言写成的语言,包括C语言)。

一、要做成什么效果? 

1.1 表面作用就这样——

先让java程序员,在Eclipse或什么IDE里,写一段java代码。比如输出一句 hello world。然后编译成一个class文件。

然后在运行我们写的C 程序,这个程序就执行那一段java代码,于是在屏幕上输出一句hello world。

1.2 应用到工作中?

将些功能,交给Java程序员实现,然后通过这套机制,实现一个由C 写的,已经编译好的程序,可以将后面业务上需要的一些新功能或变化功能,交给Java实现。这个有实际意义至少: a因为现在的一般公司组成,确实C 程序员比较少。b另外C 要把事情做好,确实比它要把事情做糟的门槛,要高得多。c最后,相比java这样有很多高阶特征的语言,c 这样太静态的语言所缺乏一些动态性,有时挺烦人的,比如就没法通过wsdl来动态生成一个ws的调用代码(因为没有反射功能)。

二、准备工作

1.1 C 方面

还是我们常用的 Code::Blocks,也还是 gcc;别的好像也没有了,当然,用微软的VC也可以用,只是一些设置的界面不一样。

1.2 Java方面

一是要装JDK

JDK和其它c,c 文件也没有什么两样,里面有提供给C,C 的源文件,有include目录,有lib目录好像。

我装在E盘,路径是:

E:\Program Files\Java\jdk1.6.0_26 。所以你也就知道了我装的jdk是什么版本的。

那些完全没玩过java的同学注意,可能你的windows里已经有装过jvm,比如安装oracle时,不过jvm只是java虚拟机,JDK才是你要在jvm上开发的SDK。因为JVM是c写的,所以它的SDK里的东东,基本就是C和C 的头文件、以及c编译出来的库文件。

二是装了一个Eclipse

当然,用不用或用什么IDE都没关系。

三是写一段java代码:

1. public class Greeting {  
2. public void SayHello() {  
3. "--------Hello C  , I'm Java.----------\n");  
4. }  
5. }

这样小的一段代码,强大的Eclipse在我存盘时,就把它编译好了。于是我立即在Java工程目录的bin子目录下,找到了 Greeting.class文件。

我没有写java的main函数及类,反正那只是约定好的入口,我们也不需要。我们准备让自己写的c 程序来决定要从java的哪个类的哪个方法执行起——说得好像很有得选择似的,其实本例中,只有一个类,叫Greeting,一个方法,叫SayHello。不是静态方法,所以调用之前,我们要在c 代码里,先创建一个对象,这是后话。

三、C 项目配置

1.1 创建C 项目

步骤一:用code::blocks的向导,生成一个空的 c 控制台(console)项目,项目名称命名为 callJava。

1.2 配置JDK头文件与库文件的搜索路径

步骤二:因为要用到jdk的头文件和库文件,我们又不想把它们都给复制一份到我们callJava的项目目录下,所以需要设置一下路径。

     这个方法有很多,最简单的是直接写绝对路径,但我不喜欢这个工程换台器就编译不了。另外我也不想这样一个临时试验性的工作,专门为java的库在c::b里设置一个全局路径变量。所以我们单独为这个项目(calljava)设置一个变量好了。

    打开项目的“build options/构建条件”对话框,然后:

   

    然后,就用这个变量名,在项目配置里,加上 jdk 头文件的包含路径:

   

   最后是 库文件的链接路径,操作类似,只是换了一页:

   

1.3为项目添加链接库

   以上配置,等于是让编译器知道上哪些个文件夹里,去找它所需要 jdk的头文件和库文件,不过最重要的是,它需要的是文件?头文件当然是在代码里写上,库文件呢,我们还需要配置一下。这个例子很简单,我们只需要一个叫 jvm.lib的文件:

   

  这个文件,你可以在一开始说的那个jdk安装子目录lib下找到。

四、C 代码

   终于到写C 代码了。就直接在向导自动生成的main.cpp里写吧。

1. #include <iostream>  
2. #include <cassert> //assert需要  
3.   
4. #include <jni.h> //jdk 的头文件  
5.   
6. using namespace std;  
7.   
8. struct JVMInfo  
9. {  
10.     JavaVM* jvm;  
11.     JNIEnv* env;  
12.       
13.     JavaVMInitArgs vm_args;  
14.       
15.     #define VM_OPT_COUNT 3  
16.     JavaVMOption options[VM_OPT_COUNT];  
17.       
18.     JVMInfo()  
19.         : jvm(0), env(0)  
20.     {  
21. const_cast<char *>("-Djava.compiler=NONE");  
22.           
23. //classpath有多个时,用";"分隔,UNIX下以":"分割。    
24. const_cast<char *>("-Djava.class.path=./demo/bin"); //这里,至少要包含前面java代码编译出来的Greeting.class文件所在路径  
25. //根据我设置的相对路径,可以推出我的callJava 的C  工程和demo的Java工程所在位置的相对关系。  
26.   
27. //用于跟踪运行时的信息    
28. const_cast<char *>("-verbose:none"); //"-verbose:jni" 换成这个,则jvm启动时,不会在屏幕上输出一堆信息  
29.           
30. //JNI版本号  
31.         vm_args.version = JNI_VERSION_1_6;    
32.         vm_args.nOptions = VM_OPT_COUNT;    
33.         vm_args.options = options;    
34.         vm_args.ignoreUnrecognized = JNI_TRUE;                    
35.     }  
36.       
37. //创建VM  
38. bool Create()  
39.     {  
40.         assert(NULL == jvm && NULL == env);  
41.           
42. //初始化虚拟机    
43. return 0 == JNI_CreateJavaVM(&jvm, (void**)(&env), &vm_args);    
44.     }  
45.       
46. //释放掉VM  
47. void Destroy()  
48.     {  
49. if (jvm)  
50.         {  
51.             jvm->DestroyJavaVM();  
52.               
53.             jvm = 0;  
54.             env = 0;  
55.         }  
56.     }  
57.       
58. //一个演示功能  
59. void Demo()  
60.     {  
61.         assert(NULL != jvm);  
62.       
63. do  
64.         {  
65. "Greeting");  
66.               
67.             #define BREAK_ON_FAIL(fail_condition, fail_msg)  if (fail_condition)  \  
68. break; }   
69.               
70. "Can't found class 'Greeting'!");  
71.               
72. //找Greeting类的构造函数  
73. "<init>", "()V");  
74.   
75. "Can't found class' ctor !");  
76.               
77. //构建一个Greeting的对象  
78.             jobject obj = env->NewObject(cls, ctor);  
79.   
80. "Can't create a object of 'Greeting'!");  
81.               
82. //找SayHello函数  
83. "SayHello", "()V");  
84.               
85. "Can't found class' method 'SayHello()'!");  
86.                   
87. //调用obj 的 SayHello 函数  
88.             env->CallObjectMethod(obj, midOfSayHello);  
89. while(false);  
90.     }      
91. };  
92.   
93. int main()  
94. {          
95.     JVMInfo jvmInfo;  
96.       
97. if (!jvmInfo.Create())  
98.     {  
99. "Create JVM fail!" << endl;  
100. return -1;  
101.     }  
102.      
103. "C          " << endl;  
104.      
105.     jvmInfo.Demo();  
106.     jvmInfo.Destroy();  
107.       
108. "C          " << endl;   
109.   
110. return 0;  
111. }

解释就看注释吧,或者在网上搜索一下同类文件。

四、运行效果

     C 代码编译通过,按F9运行……

   

    这只是一个试验用的例子,根据在当初拥Python入怀的经验教训下,知道要用这种方法来运行大的,包括多线程的java的代码,还要调用JDK中和并发有关的许多事。

   三行输出都来自同一个程序,只是其中上下两行 C 是来自C 的代码,中间一句来自Java代码。现在,我们不再管C 程序,邀请一位Java程序员,让他帮助改改那段 Greet的SayHello函数,就可以直接从运行效果中体现出来修改效果。

前言

在公司里维护一个网络后台服务端程序,用C 写的,为了一些灵活性,就想集成个脚本语言,因为lua似乎没有什么库(或者是我对它比较无知),于是就选了老牌的python。确实噢,这家伙基本什么c/c 的库,都有它的封装。于是在服务端程序里,嵌了一个python的解释器。

可惜事情没有这么美好,公司里会python本来就不多,并且多数仅在入门。

让学Java的人去学习python? 有木有发现一个现象:学java的程序员们相对都比较自我封闭,基本都不爱再学门语言什么的,爱稳定,不爱折腾(凡客体?)

好吧,我知道java不是脚本语言,但反正它编译成class之后,也是交给c/c 的程序去执行的,这么一讲,它和php,python也差不多,可以当成需要伪编译一下脚本语言来看了——呀,我知道python也可以交给net平台或jvm上运行的,s可是这两个家伙不是C写的程序吗? (最近我写一句话:世界上只有两种语言,第一种是C语言,第二种是由C语言写成的语言,包括C语言)。

一、要做成什么效果? 

1.1 表面作用就这样——

先让java程序员,在Eclipse或什么IDE里,写一段java代码。比如输出一句 hello world。然后编译成一个class文件。

然后在运行我们写的C 程序,这个程序就执行那一段java代码,于是在屏幕上输出一句hello world。

1.2 应用到工作中?

将些功能,交给Java程序员实现,然后通过这套机制,实现一个由C 写的,已经编译好的程序,可以将后面业务上需要的一些新功能或变化功能,交给Java实现。这个有实际意义至少: a因为现在的一般公司组成,确实C 程序员比较少。b另外C 要把事情做好,确实比它要把事情做糟的门槛,要高得多。c最后,相比java这样有很多高阶特征的语言,c 这样太静态的语言所缺乏一些动态性,有时挺烦人的,比如就没法通过wsdl来动态生成一个ws的调用代码(因为没有反射功能)。

二、准备工作

1.1 C 方面

还是我们常用的 Code::Blocks,也还是 gcc;别的好像也没有了,当然,用微软的VC也可以用,只是一些设置的界面不一样。

1.2 Java方面

一是要装JDK

JDK和其它c,c 文件也没有什么两样,里面有提供给C,C 的源文件,有include目录,有lib目录好像。

我装在E盘,路径是:

E:\Program Files\Java\jdk1.6.0_26 。所以你也就知道了我装的jdk是什么版本的。

那些完全没玩过java的同学注意,可能你的windows里已经有装过jvm,比如安装oracle时,不过jvm只是java虚拟机,JDK才是你要在jvm上开发的SDK。因为JVM是c写的,所以它的SDK里的东东,基本就是C和C 的头文件、以及c编译出来的库文件。

二是装了一个Eclipse

当然,用不用或用什么IDE都没关系。

三是写一段java代码:

1. public class Greeting {  
2. public void SayHello() {  
3. "--------Hello C  , I'm Java.----------\n");  
4. }  
5. }

这样小的一段代码,强大的Eclipse在我存盘时,就把它编译好了。于是我立即在Java工程目录的bin子目录下,找到了 Greeting.class文件。

我没有写java的main函数及类,反正那只是约定好的入口,我们也不需要。我们准备让自己写的c 程序来决定要从java的哪个类的哪个方法执行起——说得好像很有得选择似的,其实本例中,只有一个类,叫Greeting,一个方法,叫SayHello。不是静态方法,所以调用之前,我们要在c 代码里,先创建一个对象,这是后话。

三、C 项目配置

1.1 创建C 项目

步骤一:用code::blocks的向导,生成一个空的 c 控制台(console)项目,项目名称命名为 callJava。

1.2 配置JDK头文件与库文件的搜索路径

步骤二:因为要用到jdk的头文件和库文件,我们又不想把它们都给复制一份到我们callJava的项目目录下,所以需要设置一下路径。

     这个方法有很多,最简单的是直接写绝对路径,但我不喜欢这个工程换台器就编译不了。另外我也不想这样一个临时试验性的工作,专门为java的库在c::b里设置一个全局路径变量。所以我们单独为这个项目(calljava)设置一个变量好了。

    打开项目的“build options/构建条件”对话框,然后:

   

    然后,就用这个变量名,在项目配置里,加上 jdk 头文件的包含路径:

   

   最后是 库文件的链接路径,操作类似,只是换了一页:

   

1.3为项目添加链接库

   以上配置,等于是让编译器知道上哪些个文件夹里,去找它所需要 jdk的头文件和库文件,不过最重要的是,它需要的是文件?头文件当然是在代码里写上,库文件呢,我们还需要配置一下。这个例子很简单,我们只需要一个叫 jvm.lib的文件:

   

  这个文件,你可以在一开始说的那个jdk安装子目录lib下找到。

四、C 代码

   终于到写C 代码了。就直接在向导自动生成的main.cpp里写吧。

1. #include <iostream>  
2. #include <cassert> //assert需要  
3.   
4. #include <jni.h> //jdk 的头文件  
5.   
6. using namespace std;  
7.   
8. struct JVMInfo  
9. {  
10.     JavaVM* jvm;  
11.     JNIEnv* env;  
12.       
13.     JavaVMInitArgs vm_args;  
14.       
15.     #define VM_OPT_COUNT 3  
16.     JavaVMOption options[VM_OPT_COUNT];  
17.       
18.     JVMInfo()  
19.         : jvm(0), env(0)  
20.     {  
21. const_cast<char *>("-Djava.compiler=NONE");  
22.           
23. //classpath有多个时,用";"分隔,UNIX下以":"分割。    
24. const_cast<char *>("-Djava.class.path=./demo/bin"); //这里,至少要包含前面java代码编译出来的Greeting.class文件所在路径  
25. //根据我设置的相对路径,可以推出我的callJava 的C  工程和demo的Java工程所在位置的相对关系。  
26.   
27. //用于跟踪运行时的信息    
28. const_cast<char *>("-verbose:none"); //"-verbose:jni" 换成这个,则jvm启动时,不会在屏幕上输出一堆信息  
29.           
30. //JNI版本号  
31.         vm_args.version = JNI_VERSION_1_6;    
32.         vm_args.nOptions = VM_OPT_COUNT;    
33.         vm_args.options = options;    
34.         vm_args.ignoreUnrecognized = JNI_TRUE;                    
35.     }  
36.       
37. //创建VM  
38. bool Create()  
39.     {  
40.         assert(NULL == jvm && NULL == env);  
41.           
42. //初始化虚拟机    
43. return 0 == JNI_CreateJavaVM(&jvm, (void**)(&env), &vm_args);    
44.     }  
45.       
46. //释放掉VM  
47. void Destroy()  
48.     {  
49. if (jvm)  
50.         {  
51.             jvm->DestroyJavaVM();  
52.               
53.             jvm = 0;  
54.             env = 0;  
55.         }  
56.     }  
57.       
58. //一个演示功能  
59. void Demo()  
60.     {  
61.         assert(NULL != jvm);  
62.       
63. do  
64.         {  
65. "Greeting");  
66.               
67.             #define BREAK_ON_FAIL(fail_condition, fail_msg)  if (fail_condition)  \  
68. break; }   
69.               
70. "Can't found class 'Greeting'!");  
71.               
72. //找Greeting类的构造函数  
73. "<init>", "()V");  
74.   
75. "Can't found class' ctor !");  
76.               
77. //构建一个Greeting的对象  
78.             jobject obj = env->NewObject(cls, ctor);  
79.   
80. "Can't create a object of 'Greeting'!");  
81.               
82. //找SayHello函数  
83. "SayHello", "()V");  
84.               
85. "Can't found class' method 'SayHello()'!");  
86.                   
87. //调用obj 的 SayHello 函数  
88.             env->CallObjectMethod(obj, midOfSayHello);  
89. while(false);  
90.     }      
91. };  
92.   
93. int main()  
94. {          
95.     JVMInfo jvmInfo;  
96.       
97. if (!jvmInfo.Create())  
98.     {  
99. "Create JVM fail!" << endl;  
100. return -1;  
101.     }  
102.      
103. "C          " << endl;  
104.      
105.     jvmInfo.Demo();  
106.     jvmInfo.Destroy();  
107.       
108. "C          " << endl;   
109.   
110. return 0;  
111. }

解释就看注释吧,或者在网上搜索一下同类文件。

四、运行效果

     C 代码编译通过,按F9运行……

   

    这只是一个试验用的例子,根据在当初拥Python入怀的经验教训下,知道要用这种方法来运行大的,包括多线程的java的代码,还要调用JDK中和并发有关的许多事。

   三行输出都来自同一个程序,只是其中上下两行 C 是来自C 的代码,中间一句来自Java代码。现在,我们不再管C 程序,邀请一位Java程序员,让他帮助改改那段 Greet的SayHello函数,就可以直接从运行效果中体现出来修改效果。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhibeaci
系列文章
更多 icon
同类精品
更多 icon
继续加载