`
zhuyx808
  • 浏览: 122941 次
  • 性别: Icon_minigender_1
  • 来自: 快来看~天上米有灰机
社区版块
存档分类
最新评论

c/cpp调用java方法 实例

阅读更多
java c/cpp互相调用实例(姊妹篇之二)
                             ----------c/cpp调用java

本文是javaJNI调用c/cpp实例(姊妹篇之一)的续集c/cpp调用java。

计划第三篇写一个java安装程序实例(客户端无jre环境的安装包),以解决java程序(软件)安装不方便的问题,使java程序安装也傻瓜化。

直接进入正题:

完成本实例需要下列工具/环境:
1、java环境
2、c/cpp编辑器。windows下推荐用vs/vc++,我用的是vs2008。linux下gcc/g++

从 C/CPP 程序调用 Java 代码需要四个步骤 :
一 编写 Java 代码。
二 编译 Java 代码。
三 编写 C/C++ 代码。
四 运行本机 C/C++ 应用程序。

1、编写java代码

为了达到示范作用,java方法我用两个,一个是静态方法,一个是普通方法。

C2java.java
package com.testJni.testDemo;

public class C2java {
	public C2java(){
		super();
	}
	public static int add(int a,int b) {
		return a+b;
	}
	public boolean judge(boolean bool) {
		return !bool;
	}

}


静态方法的好处是我不用实例化,直接可以调用方法。调用起来比较简单,不容易出错。

2、编译java代码

javac 命令。(略)

3、编写 C/C++ 代码

我想在c/cpp中直接生成一个exe然后窗口输出结果,所以我就建立一个exe工程。编辑器jni环境是上篇已经搭建好的,所以这里只需要少量配置就可以了。好了,我们先建立一个工程:

打开vs2008,新建一 win32 console App 工程

键入工程名字c2java,点击OK,出来窗口点击next,选取console app

点击完成。到这里先不忙编码实现,我们先把环境搭建好,右键工程属性,选取 linker -->input,在右边窗口添加依赖jvm.lib,这个lib的位置在你%JAVA_HOME%/lib 下。如果你的路径中同我一样包含空格(例如Program Files)记得用引号括起来。

打开stdafx.h文件添加
#include <iostream>
#include <jni.h>

#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif

打开c2java.cpp,键入下面的代码
using namespace std;

int main()
{
	
  JavaVMOption options[1];
  JNIEnv *env;
  JavaVM *jvm;
  JavaVMInitArgs vm_args;
  long status;
  jclass cls;
  jmethodID mid;
  jint square;
  jboolean not;
	jobject jobj;

  options[0].optionString = "-Djava.class.path=.";
  vm_args.version = JNI_VERSION_1_2;
  vm_args.nOptions = 1;
  vm_args.options = options;
  status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
  if (status != JNI_ERR)
  {
		cls = env->FindClass("com/testJni/testDemo/C2java");
    if(cls !=0)
    { 
				mid = env->GetStaticMethodID( cls, "add", "(II)I");
        if(mid !=0)
        {  
					square = env->CallStaticIntMethod( cls, mid, 5,5);
					std::cout << square << std::endl;
	      }
				mid = env->GetMethodID(cls,"<init>","()V");
				if(mid !=0)
        {  
					jobj=env->NewObject(cls,mid);
					std::cout << "init ok" << std::endl;
	      }
				mid = env->GetMethodID( cls, "judge","(Z)Z");
				if(mid !=0)
        {  
					not = env->CallBooleanMethod(jobj, mid, 1);
					if(!not){
						std::cout << "Boolean ok" << std::endl;
					}
        }
				
    }

    jvm->DestroyJavaVM();
   return 0;
  }
  else
    return -1;

}

下面解释下上面的代码:
JavaVMOption options[] 具有用于 JVM 的各种选项设置。声明的 JavaVMOption options[] 数组足够大,就能容纳我们希望使用的所有选项。在本实例中,我们使用的选项就是类路径选项。
JNIEnv *env 表示 JNI 执行环境。
JavaVM *jvm 是指向 JVM 的指针。我们主要使用这个指针来创建、初始化和销毁 JVM。JavaVMInitArgs vm_args 表示可以用来初始化 JVM 的各种 JVM 参数。
设置参数后,创建我们的jvm :
  status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
成功返回0,不成功返回JNI_ERR。
创建完成后,我们就可以查找我们的class了,因为我们的java类一般都有包,所以我们也要加上包路径com/testJni/testDemo/C2java

在这里我们会使用到java的一个命令javap ,这个命令有什么用那,我们用javap -s -p C2java看看

打开jni.h我们会发现,Signature就是sig,也就是GetStaticMethodID( cls, "add", "(II)I")方法的第三个参数。GetStaticMethodID表示调用static方法,GetMethodID调用普通方法。下面就是传入参数,打出结果。
在看jni.h的时候我们注意到有 CallStaticXXXMethod() 和 CallXXXMethod() 之类的方法。这些方法分别代表调用静态方法和成员方法,用方法的返回类型(例如,Object、Boolean、Byte、Char、Int、Long 等等)代替变量 XXX。
静态方法和普通方法不同之处就是普通方法必须要先实例化一个java对象,调用构造器的时候方法的名称为“<init>”。

下面的代码就不用我再解释了,先是new一个实例出来,然后调用实例的方法。

最后记得销毁jvm。

代码解释完了,我们build下这个工程,生成c2java.exe。

4、运行exe

因为我们生成的exe需要调用jvm.dll初始化,为了使运行的exe不报错误,我们把%JAVA_HOME%/jre/bin/server也加进path目录。方便系统自动搜索jvm.dll。
运行结果:


最后补充:本实例并没有涉及到java的异常、java c/cpp的编码转换问题,对于异常问题,C里没有异常,请使用jni的异常处理函数。编码转换问题上篇已有介绍,此处略去。
  • 大小: 39.9 KB
  • 大小: 25.2 KB
  • 大小: 57.8 KB
  • 大小: 21.7 KB
  • 大小: 3.9 KB
分享到:
评论
3 楼 clonepig 2009-10-01  
console????  多说些可以?  比如 dll, windows gui app
2 楼 zhuyx808 2009-09-29  
xxboy 写道
请问有试过在linux环境下运行这个例子吗?

linux下肯定不会成功,您不会在linux下拿这个例子试验了一下吧?
1 楼 xxboy 2009-09-28  
请问有试过在linux环境下运行这个例子吗?

相关推荐

    JNI技术手册 c/c++调用java

    JNI是Java与本地代码之间沟通的桥梁,使得Java应用程序能够调用本地库中的方法,同时也支持从本地代码调用Java方法。 #### 二、Java调用C/C++ ##### 1. 制作DLL文件 **第一步:** 创建一个C/C++ DLL文件,通常是...

    CPP调用JAVA函数Demo

    标题 "CPP调用JAVA函数Demo" 涉及的核心技术是C++(CPP)与Java(JAVA)之间的互操作性,这通常通过Java Native Interface(JNI)实现。JNI是Java平台标准的一部分,允许Java代码和其他语言写的代码进行交互。在这个...

    JNI 调用实例(java JNI cpp互相调用实例)

    描述:JNI 调用 c++ 互相调用实例,java JNI cpp 互相调用实例 本描述进一步强调了本文的主要内容,即通过 JNI 技术实现 Java 和 C++ 之间的互相调用操作。 标签:java JNI cpp 互相调用实例 本标签对应了本文的...

    android中本地代码调用上层java的实例

    总结来说,Android中的本地代码调用上层Java实例涉及了JNI接口的使用,包括Java方法的声明、本地库的构建、以及在C/C++代码中调用Java方法的细节。这种混合编程方式让开发者能够充分利用Java和C/C++的优点,提高应用...

    Java-call-C.CPP.rar_C 调用java

    这个主题涵盖了Java应用程序如何利用本地方法(通常由C或C++编写)来扩展其功能,以及C/C++如何调用Java对象和方法。 首先,我们需要理解JNI的基本概念。JNI为Java程序员提供了一个接口,让他们可以定义本地方法,...

    ndk开发,在c中调用java中的代码

    本篇文章将详细探讨如何在NDK开发中,从C/C++代码调用Java层的方法。 首先,我们需要了解Java本地接口(JNI),它是Java平台标准版的一部分,提供了与Java虚拟机(JVM)交互的能力,包括在Java代码中调用C/C++函数...

    java-Call-CPP.rar_C 调用java

    这里通常包括了对Java对象的访问,调用Java方法,以及执行特定的C/C++逻辑。 5. **编译C/C++代码**:使用合适的编译器(如GCC或Clang)将C/C++源文件编译为动态链接库。对于Android开发,这通常涉及到使用Android ...

    jni C调用java示例

    本示例将讲解如何在Android Studio 2.3.3版本下,通过C语言调用Java方法。 首先,理解JNI的基本结构。在Java端,我们需要定义一个本地方法,即使用`native`关键字声明的方法。例如: ```java public class ...

    Java jni调用c实例

    在这个"Java jni调用c实例"中,我们将深入探讨如何通过JNI在Java应用程序中调用C语言编写的函数。 首先,我们需要了解JNI的基本结构。一个典型的JNI程序包括Java源代码、C/C++源代码以及对应的头文件。Java源代码中...

    java 的jni本地调用简单实例

    在这个简单实例中,我们将探讨如何实现这一过程,同时注意到由于Java和C++类型系统的差异,进行本地方法调用时可能需要特殊的处理。 首先,我们需要理解JNI的基本结构。在Java中,定义本地方法使用`native`关键字。...

    c++调用java工程

    对于C++调用Java而言,需要通过JNI API创建并启动一个Java虚拟机实例,然后通过这个实例访问Java类和方法。 #### 示例:C++调用Java方法 考虑一个简单的示例,其中C++调用一个Java类`WinFile`的`GetFilesFromDir`...

    java调用dll实例

    Java调用DLL实例是将Java代码与C++动态链接库(DLL)进行交互的一个常见需求。JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互,包括C、C++等。这个实例是通过JNI来...

    C++和Java互相调用实例

    本文将深入探讨如何在C++和Java之间进行互相调用的实例,主要关注Android环境下的JNI(Java Native Interface)技术,同时涉及NDK(Native Development Kit)开发。 标题:“C++和Java互相调用实例”意味着我们将...

    Android NDK开发——C回调Java中的方法

    在这个文件中,我们需要实现JNI函数,通过JNI函数调用Java接口的方法。首先,使用`JNIEnv*`指针获取到Java对象,然后调用Java接口的方法: ```cpp #include #include extern "C" JNIEXPORT void JNICALL ...

    Android NDK开发(1)----- Java与C互相调用实例详解

    例如,当C/C++代码处理完数据后,可以通过`env-&gt;CallVoidMethod()`或类似的方法来调用Java对象的非静态方法。 ```c++ void Java_com_ljt_work_LjtndkActivity_callJNIInt(JNIEnv *env, jobject thiz, jint i) { //...

    java调用C++写的dll的实例

    本实例将详细讲解如何在Java项目中调用C++编写的DLL。 首先,我们需要了解JNI的基本概念。JNI是Java平台标准的一部分,它提供了一组API,使得Java代码可以调用本地方法(即非Java代码),反之亦然。这为Java应用...

    Java调用dll示例

    总结来说,Java调用DLL主要涉及JNI的使用,包括在Java中声明native方法,生成JNI头文件,编写C++代码实现接口,编译链接DLL,以及在Java中加载和调用DLL。这个过程允许Java开发者充分利用C++的高性能特性,同时保持...

    C++调用Java接口

    本教程将详细探讨如何使用C++通过JNI(Java Native Interface)来调用Java接口。JNI是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。下面,我们将深入讲解这个过程,并结合实际例子“CInvokJava...

    java调用C#封装的dll方法

    ### Java调用C#封装的DLL方法 #### 第一种方法:Java利用JNA进行调用 **背景介绍:** 为了实现Java与C#之间的交互,一种常用的方式是通过调用C#封装的DLL文件来完成特定功能。这种方法涉及到.NET Framework与Java...

Global site tag (gtag.js) - Google Analytics