这个答案有一个替代方案,它与众不同,并且可以更自然地解决该问题,与您最初寻找的内容更接近。其他建议集中在增加重载(繁琐,手动)或使
array_classes以一种或另一种方式实现通用接口。
它忽略的是在大多数情况下都
Object非常适合
void*Java。Java中
Object的偶数[数组都是s。这意味着,如果您拥有SWIG映射
void*,
Object它将接受您可能希望传递的任何数组作为输入。稍加注意和一些JNI,我们便可以获取指向该数组开始的指针,以传递给函数。显然,我们需要拒绝
Object带有异常的non
array 。
我们仍然最终编写了一些(私有)辅助函数来安排对实际基础指针的提取,并在完成后将其释放,但是这种解决方案的好处是我们只需要执行一次,然后得到一个类型图,可以用于任何采用这样的数组的函数
void*。
我最终得到了以下用于该解决方案的SWIG界面:
%module test%{#include <stdint.h>void foo(void *in) { printf("%p, %d, %gn", in, *(jint*)in, *(jdouble*)in);}%}%typemap(in,numinputs=0) JNIEnv *env "$1 = jenv;"%javamethodmodifiers arr2voidd "private";%javamethodmodifiers arr2voidi "private";%javamethodmodifiers freearrd "private";%javamethodmodifiers freearri "private";%inline %{jlong arr2voidd(JNIEnv *env, jdoubleArray arr) { void *ptr = (*env)->GetDoubleArrayElements(env, arr, NULL); return (intptr_t)ptr;}void freearrd(JNIEnv *env, jdoubleArray arr, jlong map) { void *ptr = 0; ptr = *(void **)↦ (*env)->ReleaseDoubleArrayElements(env, arr, ptr, JNI_ABORT);}jlong arr2voidi(JNIEnv *env, jintArray arr) { void *ptr = (*env)->GetIntArrayElements(env, arr, NULL); return (intptr_t)ptr;}void freearri(JNIEnv *env, jintArray arr, jlong map) { void *ptr = 0; ptr = *(void **)↦ (*env)->ReleaseIntArrayElements(env, arr, ptr, JNI_ABORT);}%}%pragma(java) modulepre=%{ private static long arrPtr(Object o) { if (o instanceof double[]) { return arr2voidd((double[])o); } else if (o instanceof int[]) { return arr2voidi((int[])o); } throw new IllegalArgumentException(); } private static void freeArrPtr(Object o, long addr) { if (o instanceof double[]) { freearrd((double[])o, addr); return; } else if (o instanceof int[]) { freearri((int[])o, addr); return; } throw new IllegalArgumentException(); }%}%typemap(jstype) void *arr "Object"%typemap(javain,pre=" long tmp$javainput = arrPtr($javainput);",post=" freeArrPtr($javainput, tmp$javainput);") void *arr "tmp$javainput"void foo(void *arr);这为两种数组类型实现了此功能,数量有限,您也可以使用片段或宏来帮助实现这一点。SWIG在内部使用a
jlong表示指针。因此,对于每种数组类型,我们需要一个函数,该函数返回给定数组的指针,并释放另一个指针以释放它。它们是私有的,并且是模块类的一部分-除了模块,其他任何人都不需要知道它是如何工作的。
然后有两个函数
Object使用和使用
instanceof(难看,但是Java中的数组没有任何其他公共基数或接口,而泛型则无济于事)并调用正确的函数来获取/释放指针。
有了这些,只需两个类型图即可设置SWIG以将其用于所有
void*arr参数。该jstype类型表指示夜风在使用
Object了
void*在这些情况下。javain类型映射安排一个临时局部变量来保存指针(位于中
long),然后将其用于进行调用,并在调用成功或失败后进行清理。



