`

C/C++调用Java代码 创建对象、字符串操作

 
阅读更多

back>>

1. java对象的创建的步骤
    - 函数NewObject可以创建java对象
    - 用GetMethodID方法取得构造方法的jmethodID,传入方法名称设定为"<init>"表示取的是构造方法的methodID
    - 构造方法的方法返回值类型的签名始终为Void
    - 例子:

    TestNative.java

package video1;

import java.util.Date;

public class TestNative {
	public int number = 100;

	public int signTest(int i, Date date, int[] arr) {
		System.out.println("Sign Test");
		return 0;
	}
	public TestNative() {
		System.out.println("Default Constructor!");
	}
	public TestNative(int i, int j) {
		this.number = i;
		System.out.println("TestNative Constructor: i:" + i);
	}

	// native关键字修饰的方法,其内容是C/C++编写的,java中不必为它编写具体的实现
	public native void sayHello();

	public static void main(String[] args) {
		System.loadLibrary("NativeCode");
		TestNative tn = new TestNative();
		tn.sayHello();
	}
}

     C/C++代码片段:

    //找到class
    jclass clazz_Kong=env->FindClass("video1/TestNative");
    //获得构造函数ID
    jmethodID MID_Kong=env->GetMethodID(clazz_Kong,"<init>","(II)V");
    //生成对象 最后两个参数是构造函数的参数,可以不写
    jobject obj_Kong = env->NewObject(clazz_Kong,MID_Kong,1999l,2l);

    //调用属性
    jfieldID Kong_num = env->GetFieldID(clazz_Kong,"number","I");
    jint numberKong= env->GetIntField(obj_Kong,Kong_num); 
    cout<<"Kong:"<<numberKong<<endl;

     - 另一种方法 AllocObject(不常用)


2. 在C/C++本地代码中访问JAVA的String字符串对象
    - 在java中,使用的字符串String对象不论是中文还是英文符号,一个字符总是占两个字节
    - java通过JNI接口可以将java的字符串转换到C/C++中的宽字符串(wchar_t*),或是传回一个UTF-8的字符串(char*)到C/C++.
    - 反过来,C/C++可以通过一个宽字符串,或是一个UTF-8编码的字符串来创建一个java端的String对象

    - 函数GetStringChars   GetStringUTFChars
      这两个函数用来取得某个jstring对象相关的Java字符串。
      分别可以取得UTF-16编码的宽字符串(jchar*)跟UTF-8编码的字符串(char*)。
      例如:
      const jchar* GetStringChars(jstring str,jboolean* copied)
      const char* GetStringUTFChars(jstirng str,jboolean* copied)
      第一个参数传入一个指向java中的String对象的jstring变量,第二个参数传入一个jboolean的指针,是用来标识是否对java的String对象进行了拷贝。如果传入这个jboolean指针不是NULL,则它会给该指针所指向的内存传入JNI_TRUE或JNI_FALSE标识是否进行了拷贝。传入NULL表示不关心是否拷贝字符串,它就不会给jboolean*指向的内存赋值
      这两个函数分别都会有两个不同的动作:
      1.开新内存,然后把java中的string拷贝到这个内存中,然后返回指向这个内存地址的指针
      2.直接返回指向java中String内存的指针,这个时候千万不要改变这个内存的内容,这将破坏String在java中始终是常量这个原则。   
      使用这两个函数取得的字符串,在不使用的时候,要使用ReleaseStringChars/ReleaseStringUTFChars来释放拷贝的内容,或是释放对java的String对象的引用
      ReleaseStringChars(jstring jstr,const jchar * str);
      ReleaseStringUTFChars(jstring jstr,const char * str);
      第一个参数指定一个jstring变量,即是要释放的本地字符串的来源,第二个参数就是要释放的本地字符串


    - 函数GetStringCritical
      为了增加直接传回指向java字符串的指针的可能性(而不是拷贝),JDK1.2出来了新的函数

      GetStringCritical/ReleaseStringCritical.
      在GetStringCritical/ReleaseStringCritical之间是一个关键区,在关键区千万不要出现中断操作,或是在JVM中分配任何新对象,否则会造成JVM死锁
      虽说这个函数会增加直接传回指向java字符串指针的可能性,不过还是会根据实际情况传回拷贝过的字符串
      不支持GetStringUTFCritical

    - 函数GetStringRegion/GetStringUTFRegion
      动作:把java字符串的内容直接拷贝到C/C++的字符数组中。在呼叫这个函数之前必须有一个C/C++分配出来的字符串,然后传入到这个函数中进行字符串的拷贝(此函数不分配内存)
      例子:
      //拷贝Java字符串并以UTF-8编码传入buffer
      GetStringUTFRegion(jstring str,jsize start,jsize len,char* buffer);
      //拷贝java字符串并以UTF-16编码传入buffer
      GetStringRegion(jstring str, jsize start,jsize len,jchar* buffer);



3. 在C/C++本地代码中创建JAVA的String字符串对象

    - 函数

    jstring NewString(const jchar* str,jsize len);
    jstring NewStringUTF(const char * str);
    //取得字符串的长度
    jsize GetStringLength(jstring str);
    jsize GetStringUTFLength(jstring str);

4. 字符串操作完整示例

    TestNative1.java

package video1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestNative1 {

	public String message = null;

	public native void callCppFunction();

	public static void main(String[] args) throws IOException {
		System.loadLibrary("NativeCode");
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				System.in));
		String str = reader.readLine();
		TestNative1 obj = new TestNative1();

		obj.message = str;
		obj.callCppFunction();
		System.out.println("java output:" + obj.message);
	}
}

     cpp.cpp

#include "video1_TestNative1.h"
#include "windows.h"
#include <iostream>
using namespace std;

JNIEXPORT void JNICALL Java_video1_TestNative1_callCppFunction(JNIEnv * env, jobject obj){
	
	jclass native_clazz = env->GetObjectClass(obj);
	//得到jfieldID
	jfieldID fieldID_msg = env->GetFieldID(native_clazz,"message","Ljava/lang/String;");

	//得到java字符串
	jstring j_msg =(jstring) env->GetObjectField(obj,fieldID_msg);
	//将java字符串转换为本地字符串
	const jchar * jstr = env->GetStringChars(j_msg,NULL);
	MessageBoxW(NULL,(const wchar_t*)jstr,L"Title",MB_OK);//对话框弹出
	env->ReleaseStringChars(j_msg,jstr);//释放资源
	//修改字符串
}
 

 

  • 大小: 10.5 KB
分享到:
评论

相关推荐

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

    通过以上详细的步骤和技术要点,我们可以看到,无论是Java调用C/C++还是C/C++调用Java,都需要仔细地处理数据类型转换、异常处理以及性能优化等问题。掌握这些技术细节,对于开发高效稳定的跨语言应用程序至关重要。

    在 C/C++ 中调用 Java

    调用Java方法时,需要将C/C++的数据转换为Java类型,比如使用`NewObjectArray()`创建对象数组,`NewStringUTF()`创建字符串等。同样,Java方法的结果也需要转换回C/C++的数据类型。 7. **释放资源**: 完成调用后...

    c++调用java工程

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

    aes c/c++和java互通

    总的来说,AES在C/C++和Java之间的互通涉及到密钥管理、加密模式选择、数据编码和解码,以及相应的库函数调用。通过合理的设计和实现,可以确保两个平台之间加密数据的安全传输。具体实现细节可以参考提供的示例代码...

    NDK开发之C语言调用Java构造方法、父类方法、返回中文字符串乱码问题案例

    在Android开发中,NDK(Native ...总之,NDK开发中的C/C++调用Java方法是一项关键技能,它能让你充分利用原生代码的优势,同时解决Java层难以处理的问题。理解和熟练运用JNI,将使你的Android应用性能更上一层楼。

    JNI 教程 java与c/c++互相调用

    - **字符串处理**:JNI提供了处理Java字符串到C字符串和反向转换的函数。 4. **示例与调试** - **Hello World示例**:一个简单的例子是创建一个Java类,声明一个`native`方法,然后在C/C++中实现该方法,打印...

    java写的一个使用jni调用c/c++的dll

    在这个C++函数中,`JNIEnv *env`提供了访问Java对象、类、字符串等的接口,`jobject obj`是Java对象的引用,可以通过它访问其他Java字段或方法。 编译C/C++代码成DLL文件,这通常涉及到设置正确的编译器选项和链接...

    java与c交互传递字符串和整型

    在JNI中,我们使用`NewStringUTF`函数从Java字符串创建一个C的UTF-8编码的字符串,然后使用`GetStringUTFChars`获取其实际内容。在C中处理完字符串后,需要使用`ReleaseStringUTFChars`释放资源。这个过程确保了内存...

    visual studio 2019下C++通过JNI调用JAVA代码

    在本文中,我们将深入探讨如何在Visual Studio 2019环境下使用C++通过Java Native Interface (JNI)来调用Java代码。JNI是Java平台的一部分,它为Java应用程序提供了与本地代码交互的能力,使得开发者可以将Java应用...

    使用C++创建java虚拟机JVM,使用JNI调用java函数.zip

    在提供的资源"使用C++创建java虚拟机JVM,使用JNI调用java函数"中,可能详细介绍了以上步骤的实际应用,包括代码示例和可能遇到的问题及解决方案。通过学习和实践这个教程,开发者可以更好地理解和掌握C++与Java之间...

    Android JNI c/c++调用java的实例

    以下是一个简单的Android JNI C/C++调用Java方法的实例: 1. **获取JNIEnv和jclass参数** 当Java代码调用 native 方法时,系统会自动传递JNIEnv指针和当前类的jclass对象。例如,在Java中声明一个native方法: `...

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

    8. **释放资源**:在完成C/C++调用Java的操作后,别忘了释放任何已分配的资源,如释放局部引用(`DeleteLocalRef`)以避免内存泄漏。 在“Java call C.C++.ppt”这个演示文稿中,很可能会详细介绍上述各个步骤,...

    JNA调用c/c++库示例

    Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用C/C++等本地库,而无需编写JNI(Java Native Interface)代码。JNA通过映射函数调用和数据类型,提供了相对简洁的接口来与本地操作系统...

    C/C++参考手册.chm(共三本.chm)

    2. **c++库函数(en).CHM**:这部分是C++库函数的英文版文档,详细列出了C++标准库中的各种函数,如输入/输出流(iostream)、字符串操作(string)、容器(如vector、list、set、map)、算法(如排序、查找)等。...

    java调用c语言

    在跨语言编程中,Java调用C语言是一种常见的场景,特别是在需要与操作系统底层交互或利用已有C语言库的情况下。Java Native Interface (JNI) 是实现这一功能的核心技术。本文将详细介绍Java调用C语言的基本原理、所...

    C++调用Javawebservice.pdf

    总的来说,C++调用Java Web Service涉及到的主要步骤包括:生成C++客户端代理类、构建SOAP请求、发送请求并解析响应。过程中可能需要借助如MS SOAP Toolkit这样的工具进行调试和监控,确保通信的正确性。对于复杂的...

    Android Java代码与JNI交互字符串转换(四)

    在Android开发中,Java代码与原生C/C++代码(JNI,Java Native Interface)的交互是一种常见的技术,尤其是在性能敏感或者需要调用操作系统底层API的场景。本篇将深入探讨如何在Java和JNI之间进行字符串转换,这是...

    Android代码调用C++

    - **字符串转换**: 使用`JNIEnv`提供的函数,如`GetStringUTFChars`获取Java字符串的UTF-8表示,`NewString`创建Java字符串。 - **对象转换**: 通过JNI接口操作Java对象,如获取字段值、调用方法等。 **6. C++代码...

Global site tag (gtag.js) - Google Analytics