Java JNI: Java 本机接口

GetMethodID函数声明如下:

jmethodID (JNICALL *GetMethodID) (JNIEnv *env, jclass clazz, const char *name, const char *sig);

获取Java对象方法的jmethodID。包括构造方法,构造方法是一种特殊的方法,但在JVM层面和其他的方式是一样的。

参数说明:

env: 上面已经说明

clazz:表示对象类,如Object.class。

name:方法名,如果是得到构造方法的jmethodID,该参数固定为<init>。

sig:方法签名,形式如下:

(参数类型签名列表)返回类型签名。

扫描二维码关注公众号,回复: 5263043 查看本文章

如无参构造方法:public JniNewTestObjectX()

或者public void testMethod()方法定义,它的签名为:

()V

如无参构造方法:public JniNewTestObjectX(int i, String s)

或者public void testMethod(int i, String s)方法定义,它的签名为:

(ILjava/lang/String;)V

Java JNI: Java 本机接口可以采用C开发,也支持C++。

 

例子:

C开发的例子。

 

public class JniCallMethodReturnVoidTest {
	static {  
        System.loadLibrary("libjnitest");  
    }

	public static void main(String[] args) {
	  JniNewTest obj = new JniNewTest();
	  obj.testMethod();
	}
}

class JniNewTest {
	public native void testMethod();
}

 

>javac JniCallMethodReturnVoidTest.java

 

>javah -jni -d . JniNewTest

 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniNewTest */

#ifndef _Included_JniNewTest
#define _Included_JniNewTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JniNewTest
 * Method:    testMethod
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JniNewTest_testMethod
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

 

实现:

#include "JniNewTest.h"
JNIEXPORT void JNICALL Java_JniNewTest_testMethod
  (JNIEnv *env, jobject jobj)
{
    printf("debug: Java_JniNewTest_testMethod.\n");
}

 

 

>cl /GR /GX /W3 /ID:\usr\bin\jdk1.6.0_12\include /ID:\usr\bin\jdk1.6.0_12\include\win32 /c /Fo.\ JniNewTest.c

 

>link /DLL /OUT:.\libjnitest.dll .\JniNewTest.obj

 

>java JniCallMethodReturnVoidTest
debug: Java_JniNewTest_testMethod.

 

 

Java native开发

目录结构:

>tree /F .

Folder PATH listing for volume D

Volume serial number is F075-351A

└───com

    └───jx

            com_jx_Object.c

            com_jx_Object.dll

            com_jx_Object.exp

            com_jx_Object.h

            com_jx_Object.lib

            com_jx_Object.obj

            libobj.dll

            libobj.exp

            libobj.lib

            Object.class

            Object.java

            ObjectTest.java

Object:

package com.jx;

public class Object {

	public native int addr();
	
	static {
		System.loadLibrary("libobj");
	}
}
>javac com\jx\Object.java
 
>javah -jni -d com\jx com.jx.Object
 

com_jx_Object.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jx_Object */

#ifndef _Included_com_jx_Object
#define _Included_com_jx_Object
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jx_Object
 * Method:    addr
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_jx_Object_addr
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
 

com_jx_Object.c:

#include <stdio.h>

#include "com_jx_Object.h"

JNIEXPORT jint JNICALL Java_com_jx_Object_addr
  (JNIEnv *env, jobject jobj)
{
  printf("Java_com_jx_Object_addr.\n");
  return 0;
}
 

编译:

>cl /GX /W3 /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /c /Fo.\ *.c 
连接生成库文件:
>link /DLL /OUT:.\libobj.dll .\*.obj

也可以使用以下命令一次就生成库文件

# 也可以使用以下命令一次就生成库文件:
>cl /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /LD com_jx_Object.c
 

将生成的库文件libobj.dll放在path目录下:

public static void main(String[] args) {
	String libPath = System.getProperty("java.library.path");
	System.out.println(libPath);
	Object obj = new Object();
	obj.addr();
}
 
运行结果
<java.library.path>
Java_com_jx_Object_addr.
Java JNI开发实例:实例化Java对象
在这个例子中,在Java Runtime(Java运行时环境)层面通过NewObject函数创建Java对象(对象实例化),这种方式和在Java层面实例化对象(如new ... ...)效果是一样的。
NewObject函数定义如下:
jobject (JNICALL *NewObject) (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
Java通过构造方法 实例化对象, 构造方法是一种特殊的方法,但在JVM层面和其他的方式是一样的,所以在 Java Runtime(Java运行时环境)层面通过NewObject函数创建Java对象(对象实例化)需要指定构造方法。
参数说明:
env:上面已经说明
clazz:表示构造对象的类
methodID:表示函数标识,这里是 构造函数,通过 GetMethodID得到函数标识(包括构造函数)。
最后一个 不定长参数列表表示传给 构造函数的参数列表。
变体:
jobject (JNICALL *NewObjectV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
NewObjectV和 NewObject不同的是在调用构造函数的传参上,也就是最后一个参数, NewObjectV在 构造函数的参数传参上采用的是不定长参数列表: va_list。
jobject (JNICALL *NewObjectA) (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
NewObjectV和 NewObject不同的是在调用构造函数的传参上,也就是最后一个参数, NewObjectV在 构造函数的参数传参上采用的是jvalue指针
class JniNewTestObject {
	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
class JniNewTestObjectX {

    private int i;

	private String s;

	public JniNewTestObjectX() {
	
	}

	public JniNewTestObjectX(int i, String s) {
	  this.i = i;
	  this.s = s;
	}

	public int i() {
	  return i;
	}

	public String s() {
	  return s;
	}

	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
abstract class JniNewTestAbstractObject 
{
	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
class JniNewTestObjectConstructor {
	public native JniNewTestObject constructJniNewTestObject(Class<?> clazz);

	public native JniNewTestObjectX constructJniNewTestObjectX(Class<?> clazz);

	public native JniNewTestObjectX constructJniNewTestObjectX(Class<?> clazz, int i, String s);

	public native JniNewTestAbstractObject constructJniNewTestAbstractObject(Class<?> clazz);
}
 
public class JniNewObjectTest {
	static {  
        System.loadLibrary("libjnitest");  
    }

	public static void main(String[] args) {
	  JniNewTestObjectConstructor constructor = new JniNewTestObjectConstructor();
	  JniNewTestObject obj = constructor.constructJniNewTestObject(JniNewTestObject.class);
	  if (obj == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(obj.toString());
	  }

	  JniNewTestObjectX objx1 = constructor.constructJniNewTestObjectX(JniNewTestObjectX.class);
	  if (objx1 == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(objx1.toString());
		System.out.println(objx1.i());
		System.out.println(objx1.s());
	  }

	  JniNewTestObjectX objx2 = constructor.constructJniNewTestObjectX(JniNewTestObjectX.class, 1234, "this is 1234.");
	  if (objx2 == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(objx2.toString());
		System.out.println(objx2.i());
		System.out.println(objx2.s());
	  }

	  JniNewTestAbstractObject aobj = constructor.constructJniNewTestAbstractObject(JniNewTestAbstractObject.class);
	  if (aobj == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(aobj.toString());
	  }
	}
}
 
>javac JniNewObjectTest.java
 为JniNewTestObjectConstructor生成本机接口:JniNewTestObjectConstructor.h
>javah -jni -d . JniNewTestObjectConstructor
 
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniNewTestObjectConstructor */

#ifndef _Included_JniNewTestObjectConstructor
#define _Included_JniNewTestObjectConstructor
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObject
 * Signature: (Ljava/lang/Class;)LJniNewTestObject;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObject
  (JNIEnv *, jobject, jclass);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObjectX
 * Signature: (Ljava/lang/Class;)LJniNewTestObjectX;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2
  (JNIEnv *, jobject, jclass);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObjectX
 * Signature: (Ljava/lang/Class;ILjava/lang/String;)LJniNewTestObjectX;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2ILjava_lang_String_2
  (JNIEnv *, jobject, jclass, jint, jstring);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestAbstractObject
 * Signature: (Ljava/lang/Class;)LJniNewTestAbstractObject;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestAbstractObject
  (JNIEnv *, jobject, jclass);

#ifdef __cplusplus
}
#endif
#endif
 
实现 本机接口(JniNewTestObjectConstructor.h):JniNewTestObjectConstructor.c
#include "JniNewTestObjectConstructor.h"

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObject(JNIEnv *env, jobject jobj, jclass jclazz)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestObject()
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2(JNIEnv *env, jobject jobj, jclass jclazz)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestObjectX()
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2ILjava_lang_String_2(JNIEnv *env, 
    jobject jobj, 
	jclass jclazz, 
	jint i, jstring s)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "(ILjava/lang/String;)V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id, i, s); // public JniNewTestObjectX(int i, String s)
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestAbstractObject(JNIEnv *env, jobject jobj, jclass jclazz) 
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestAbstractObject(), class JniNewTestAbstractObject declares abstract.
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}
 
 
>cl /GR /GX /W3 /ID:\usr\bin\jdk1.6.0_12\include /ID:\usr\bin\jdk1.6.0_12\include\win32 /c /Fo.\ *.c
 
>link /DLL /OUT:.\libjnitest.dll .\*.obj
 运行结果:
>java JniNewObjectTest
JniNewTestObject@1fb8ee3: jni new object.
JniNewTestObjectX@14318bb: jni new object.
0
null
JniNewTestObjectX@ca0b6: jni new object.
1234
this is 1234.
err: NewObject, return null.Exception in thread "main" java.lang.InstantiationEx
ception: JniNewTestAbstractObject
        at JniNewTestObjectConstructor.constructJniNewTestAbstractObject(Native
Method)
        at JniNewObjectTest.main(JniNewObjectTest.java:33)
 

Java native开发

目录结构:

>tree /F .

Folder PATH listing for volume D

Volume serial number is F075-351A

└───com

    └───jx

            com_jx_Object.c

            com_jx_Object.dll

            com_jx_Object.exp

            com_jx_Object.h

            com_jx_Object.lib

            com_jx_Object.obj

            libobj.dll

            libobj.exp

            libobj.lib

            Object.class

            Object.java

            ObjectTest.java

Object:

package com.jx;

public class Object {

	public native int addr();
	
	static {
		System.loadLibrary("libobj");
	}
}
>javac com\jx\Object.java
 
>javah -jni -d com\jx com.jx.Object
 

com_jx_Object.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jx_Object */

#ifndef _Included_com_jx_Object
#define _Included_com_jx_Object
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jx_Object
 * Method:    addr
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_jx_Object_addr
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
 

com_jx_Object.c:

#include <stdio.h>

#include "com_jx_Object.h"

JNIEXPORT jint JNICALL Java_com_jx_Object_addr
  (JNIEnv *env, jobject jobj)
{
  printf("Java_com_jx_Object_addr.\n");
  return 0;
}
 

编译:

>cl /GX /W3 /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /c /Fo.\ *.c 
连接生成库文件:
>link /DLL /OUT:.\libobj.dll .\*.obj

也可以使用以下命令一次就生成库文件

# 也可以使用以下命令一次就生成库文件:
>cl /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /LD com_jx_Object.c
 

将生成的库文件libobj.dll放在path目录下:

public static void main(String[] args) {
	String libPath = System.getProperty("java.library.path");
	System.out.println(libPath);
	Object obj = new Object();
	obj.addr();
}
  运行结果
<java.library.path>
Java_com_jx_Object_addr.
Java JNI开发实例:实例化Java对象 在这个例子中,在Java Runtime(Java运行时环境)层面通过NewObject函数创建Java对象(对象实例化),这种方式和在Java层面实例化对象(如new ... ...)效果是一样的。 NewObject函数定义如下: jobject (JNICALL *NewObject) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); Java通过构造方法 实例化对象, 构造方法是一种特殊的方法,但在JVM层面和其他的方式是一样的,所以在 Java Runtime(Java运行时环境)层面通过NewObject函数创建Java对象(对象实例化)需要指定构造方法。 参数说明: env:上面已经说明 clazz:表示构造对象的类 methodID:表示函数标识,这里是 构造函数,通过 GetMethodID得到函数标识(包括构造函数)。 最后一个 不定长参数列表表示传给 构造函数的参数列表。 变体: jobject (JNICALL *NewObjectV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); NewObjectV和 NewObject不同的是在调用构造函数的传参上,也就是最后一个参数, NewObjectV在 构造函数的参数传参上采用的是不定长参数列表: va_list。 jobject (JNICALL *NewObjectA) (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); NewObjectV和 NewObject不同的是在调用构造函数的传参上,也就是最后一个参数, NewObjectV在 构造函数的参数传参上采用的是jvalue指针
class JniNewTestObject {
	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
class JniNewTestObjectX {

    private int i;

	private String s;

	public JniNewTestObjectX() {
	
	}

	public JniNewTestObjectX(int i, String s) {
	  this.i = i;
	  this.s = s;
	}

	public int i() {
	  return i;
	}

	public String s() {
	  return s;
	}

	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
abstract class JniNewTestAbstractObject 
{
	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
class JniNewTestObjectConstructor {
	public native JniNewTestObject constructJniNewTestObject(Class<?> clazz);

	public native JniNewTestObjectX constructJniNewTestObjectX(Class<?> clazz);

	public native JniNewTestObjectX constructJniNewTestObjectX(Class<?> clazz, int i, String s);

	public native JniNewTestAbstractObject constructJniNewTestAbstractObject(Class<?> clazz);
}
 
public class JniNewObjectTest {
	static {  
        System.loadLibrary("libjnitest");  
    }

	public static void main(String[] args) {
	  JniNewTestObjectConstructor constructor = new JniNewTestObjectConstructor();
	  JniNewTestObject obj = constructor.constructJniNewTestObject(JniNewTestObject.class);
	  if (obj == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(obj.toString());
	  }

	  JniNewTestObjectX objx1 = constructor.constructJniNewTestObjectX(JniNewTestObjectX.class);
	  if (objx1 == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(objx1.toString());
		System.out.println(objx1.i());
		System.out.println(objx1.s());
	  }

	  JniNewTestObjectX objx2 = constructor.constructJniNewTestObjectX(JniNewTestObjectX.class, 1234, "this is 1234.");
	  if (objx2 == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(objx2.toString());
		System.out.println(objx2.i());
		System.out.println(objx2.s());
	  }

	  JniNewTestAbstractObject aobj = constructor.constructJniNewTestAbstractObject(JniNewTestAbstractObject.class);
	  if (aobj == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(aobj.toString());
	  }
	}
}
 
>javac JniNewObjectTest.java
 为JniNewTestObjectConstructor生成本机接口:JniNewTestObjectConstructor.h
>javah -jni -d . JniNewTestObjectConstructor
 
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniNewTestObjectConstructor */

#ifndef _Included_JniNewTestObjectConstructor
#define _Included_JniNewTestObjectConstructor
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObject
 * Signature: (Ljava/lang/Class;)LJniNewTestObject;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObject
  (JNIEnv *, jobject, jclass);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObjectX
 * Signature: (Ljava/lang/Class;)LJniNewTestObjectX;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2
  (JNIEnv *, jobject, jclass);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObjectX
 * Signature: (Ljava/lang/Class;ILjava/lang/String;)LJniNewTestObjectX;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2ILjava_lang_String_2
  (JNIEnv *, jobject, jclass, jint, jstring);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestAbstractObject
 * Signature: (Ljava/lang/Class;)LJniNewTestAbstractObject;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestAbstractObject
  (JNIEnv *, jobject, jclass);

#ifdef __cplusplus
}
#endif
#endif
  实现 本机接口(JniNewTestObjectConstructor.h):JniNewTestObjectConstructor.c
#include "JniNewTestObjectConstructor.h"

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObject(JNIEnv *env, jobject jobj, jclass jclazz)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestObject()
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2(JNIEnv *env, jobject jobj, jclass jclazz)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestObjectX()
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2ILjava_lang_String_2(JNIEnv *env, 
    jobject jobj, 
	jclass jclazz, 
	jint i, jstring s)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "(ILjava/lang/String;)V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id, i, s); // public JniNewTestObjectX(int i, String s)
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestAbstractObject(JNIEnv *env, jobject jobj, jclass jclazz) 
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestAbstractObject(), class JniNewTestAbstractObject declares abstract.
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}
   
>cl /GR /GX /W3 /ID:\usr\bin\jdk1.6.0_12\include /ID:\usr\bin\jdk1.6.0_12\include\win32 /c /Fo.\ *.c
 
>link /DLL /OUT:.\libjnitest.dll .\*.obj
 运行结果:
>java JniNewObjectTest
JniNewTestObject@1fb8ee3: jni new object.
JniNewTestObjectX@14318bb: jni new object.
0
null
JniNewTestObjectX@ca0b6: jni new object.
1234
this is 1234.
err: NewObject, return null.Exception in thread "main" java.lang.InstantiationEx
ception: JniNewTestAbstractObject
        at JniNewTestObjectConstructor.constructJniNewTestAbstractObject(Native
Method)
        at JniNewObjectTest.main(JniNewObjectTest.java:33)
 

猜你喜欢

转载自lobin.iteye.com/blog/2437928
今日推荐