1

我声明了一个内联本机 JNI 函数 getId。我不确定如何在下面的 %native 片段中告诉 SWIG 如何只返回 java.lang.Object。我现在有待定。我相信类型映射是正确的方法,但我不确定如何使用 %native 函数为原生 JNI 方法声明它。有任何想法吗?

%module Sample
%{
JNIEXPORT jobject JNICALL Java_com_test_SampleJNI_getID(JNIEnv *env, jclass cls) 
{
    jmethodID cnstrctr;
    jvalue args[2];
    jobject obj;
    jbyteArray bArray;

    bArray = (*env)->NewByteArray(env, 32);

   (*env)->SetByteArrayRegion(env, bArray, 0, 32, (jbyte *)foo);

   cls = (*env)->FindClass(env, "com/test/jni/DeviceId");
   cnstrctr = (*env)->GetMethodID(env, cls, "<init>", "(ILjava/lang/String;[B)V");

   args[0].i = (*env)->NewStringUTF(env, "id");
   args[1].i = bArray;

   obj = (*env)->NewObjectA(env, cls, cnstrctr, args);

   return obj;
}
%}
%native(getID) TBD getID();

设备ID.java:

package com.test.jni;

public class DeviceId {
    private String id;
    private byte[] cache;

    public DeviceId(String id, byte[] cache){
        this.id=id;
        this.cache=cache;
    }

    public byte[] getCache() {
        return cache;
    }

    public void setCache(byte[] cache) {
        this.cache = cache;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }   
}
4

1 回答 1

1

您可以将类型映射(例如最有可能的 jtype 和 jstype)与 一起使用%native,但您也可以简单地说jobject如果您有一个Object被返回并为您处理它,例如:

%module Sample
%{
JNIEXPORT jobject JNICALL Java_com_test_SampleJNI_getID(JNIEnv *env, jclass cls) 
{
  jclass c = (*jenv)->FindClass(env, "java/lang/Object");
  jmethodID m = (*jenv)->GetMethodID(env, c, "<init>", "()V");
  return (*env)->NewObject(env, c, m);
}
%}
%native(getID) jobject getID();

如果您想返回其他内容(例如 java.lang.Integer),您可以执行以下操作:

%module Sample
%{
JNIEXPORT jobject JNICALL Java_com_test_SampleJNI_getID(JNIEnv *env, jclass cls) 
{
  jclass c = (*jenv)->FindClass(env, "java/lang/Integer");
  jmethodID m = (*jenv)->GetMethodID(env, c, "<init>", "()V");
  return (*env)->NewObject(env, c, m);
}
%}

%typemap(jstype) int getID "Integer"
%typemap(jtype) int getID "Integer"
%native(getID) int getID();

我在该类型映射中明确指定了 getID 以避免将其应用于所有ints。

(我测试了 SWIG 部分正在生成合理的代码,但我没有验证 JNI,它显然需要检查返回值)


对于您的具体示例,您可以执行以下操作:

%typemap(jstype) DeviceID getID "com.test.jni.DeviceId"
%typemap(jtype) DeviceID getID "com.test.jni.DeviceId"
%typemap(javaout) DeviceID getID { return $jnicall; }
%native(getID) DeviceID getID();

即,您可以写出任何尚未用于其他用途的名称,只需应用类型映射即可。

但是最好使用jobject返回类型,因为你可以写:

%typemap(jstype) jobject getID "com.test.jni.DeviceId"
%typemap(jtype) jobject getID "com.test.jni.DeviceId"
%native(getID) jobject getID();
于 2012-04-12T16:23:15.877 回答