我正在为C库开发一些SWIG生成的Java绑定。该库包含采用类型参数的函数void *
。在C端,这些通常会作为指向类型数组的指针传递float
或转换int
为void *
。在生成的Java绑定中,这导致采用类型参数的方法SWIGTYPE_p_void
。
在Java绑定中构造float / int数组的最佳方法是什么,以便可以将它们作为类型传递SWIGTYPE_p_void
给这些方法?
目前,我在example.i文件中定义了一个辅助函数:
void *floata_to_voidp(float f[])
{
return (void *)f;
}
然后在Java方面执行以下操作:
float foo[] = new float[2];
SWIGTYPE_p_void av = null;
// do something with foo
av = example.floata_to_voidp(foo);
example.myfunction(av);
这似乎很难看,尤其是inta_to_voidp()
对于我要支持的每种类型转换,我也需要在SWIG接口文件中添加一个etc。
有没有没有辅助功能的方法,而在Java端包含较少的额外代码来转换数据类型的方法?
更新(17/6/12): 为这个问题提供更多细节:我正在尝试做的是使用一组C函数,并带有原型int foo(const float *data, int N, const void *argv, float *result)
并将它们映射到Java端的方法,在该方法中可以使用任意类型的数组作为传递argv
。请注意,argv
是const void *
与不是void *
。
这个答案有一个替代方案,它与众不同,并且可以更自然地解决该问题,与您最初寻找的内容更接近。其他建议集中在增加重载(繁琐,手动)或使array_class
es以一种或另一种方式实现通用接口。
它忽略的是在大多数情况下都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, %g\n", 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) modulecode=%{
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
),然后将其用于进行调用,并在调用成功或失败后进行清理。
错误CS0234:类型或命名空间名称com.sushi.hangover”中不存在。是否缺少程序集引用? 我有一个Android绑定项目,它有从多个接口继承的类,但这些接口没有生成,因此依赖于它们的所有公共类都无法绑定。 如您所见,该接口的没有设置为,因此不会生成C#代码,但是begin生成了依赖于该接口的公共类: 绑定在将接口名称从转换为时,可以识别接口。 是否有任何方法可以强制创建这些接口,而
在的内部类中。 演员们在这里是怎么工作的?我在这里期待,因为我们要将一个纯超类对象转换为子类。
问题内容: 我想在一个程序包中打印所有的类名,并在每个程序包中打印相应的属性及其数据类型。 在一个代码中,我能够以字符串形式获取类名。在另一个代码中,我可以使用以下方法获取属性及其数据类型 但是我想合并两个代码。由于在第一个代码中我以字符串的形式获得了类名,我无法使用,因为这里是类型。 因此,我需要一种将“ 类名”从类型转换为类型的方法。 我试过了,但是没有用。 问题答案: 确保是完全合格的类名,
何时会生成绑定类,这里是ActivityMainBinding。我有编译时错误。“无法解析ActivityMainBinding”。 感谢任何帮助。谢谢
我有一个界面 有几个像这样的类 这里重要的是,实现的所有类(如)都具有方法,但该方法不是接口的一部分。 现在,我需要将一些XML反序列化为一个Java对象。XML可以是任何实现类的对象,但是在反序列化之后,我将需要使用方法。 有什么简洁或优雅的方法来实现这一点吗? 我创建了另一个界面 并尝试创建它的实例 但在将XML强制转换为对象时会出现一个错误,该错误指出Bar的object类型的对象
问题内容: 我是Java的新手,想知道double转换为int cast如何工作吗?我知道,只需将低32位转换为int就很容易了,但是将double(64位)转换为int(32位)呢?来自二进制的double中的那64位是Double- precision浮点格式(Mantissa),那么它如何在内部转换为int? 问题答案: 所有这些都记录在JLS的5.1.3节中。 第一步,将浮点数转换为lon