SWIG文档解释了C语言中的各种输入类型,比如:
void spam1(Foo *x); // Pass by pointer
void spam2(Foo &x); // Pass by reference
void spam3(Foo x); // Pass by value
void spam4(Foo x[]); // Array of objects..。都会在Java中接受一种类型的参数,如下所示:
Foo f = new Foo(); // Create a Foo
example.spam1(f); // Ok. Pointer
example.spam2(f); // Ok. Reference
example.spam3(f); // Ok. Value.
example.spam4(f); // Ok. Array (1 element)类似地,对于C:中的返回类型:
Foo *spam5();
Foo &spam6();
Foo spam7();..。这三个函数都将返回一个指向某个Foo对象的指针,该指针将被分配给一个Java对象变量,最后一个函数需要分配一个值类型,Java垃圾回收将在释放时处理该值类型。
但是假设spam5()返回一个指向数组的指针。在Java中,我必须使用数组语义来访问各个元素,但我不认为我可以这样做:
Foo foo[] = spam5();我甚至不认为编译器会接受(Foo[])的类型转换,那么这在SWIG中是如何工作的呢?
发布于 2009-10-06 21:40:57
这个问题没有简单或自动的解决方案。相信我,我找过了。
问题是SWIG不知道返回的数组应该有多大,所以它不能生成Java数组。您也不能将大小作为参数提供给函数(尽管可能是粗略的)-类型映射不会以这种方式工作。
在一般情况下,您必须编写另一个包装器函数,该函数接受一个C数组和一个长度作为输出参数,并使用类型映射将这两个参数转换为Java数组。或者,如果您不介意使用carrays.i,您可以跳过第二步,直接使用Java中的C数组。
发布于 2009-10-23 22:28:55
您可以直接使用JNI:
假设您想要检索一个xyz向量数组
public class demo{
public native vecteur[] returnArray();
....
}在swig wrap cxx文件中,添加将填充java vect数组的函数
JNIEXPORT jobjectArray JNICALL
Java_demo_returnArray
(JNIEnv *env, jobject jobj){
jobjectArray ret;
int i;
jclass objClass;
jmethodID mid;
jobject myobj;
jmethodID setX;
objClass = env->FindClass("vect");
if (!objClass)
{
printf("class not found\n");
exit(0);
}
ret= (jobjectArray)env->NewObjectArray(5, // change with the size of your array or a variable
objClass,
env->NewStringUTF(""));//FIXME
// call javap -s myclass to know the names
mid=env->GetMethodID( objClass, "<init>", "()V"); // looking for the vect class constructor
if (!mid)
{
printf("vect() not found\n");
exit(0);
}
for(i=0;i<5;i++) {
myobj=env->NewObject( objClass, mid); // myobj = new vect()
// get vect::setX method
setX=env->GetMethodID( objClass, "setX", "(F)V"); // looking for vect::setX method
if(!setX)
{
printf("method vect::setX not found\n");
exit(0);
}
// call setX method with param i
env->CallVoidMethod(myobj, setX,(float)i); // change i with your array value
env->SetObjectArrayElement(
ret,i,myobj);
}
return(ret);
}最后是主类
// main.java
public class main {
static {
System.loadLibrary("myclass");
}
public static void main(String argv[]) {
demo l = new demo();
vecteur f[] = l.returnArray();
System.out.println("array size : "+f.length);
for (int i = 0;i < f.length;i++)
System.out.println(f[i].getX());
}
}发布于 2009-10-06 21:41:41
在java中,数组是一个对象,因此,如果spam5()返回Object,那么编译器将允许您将其转换为Foo的数组。这是有效的Java:
class Bar {
static class Foo {}
Foo[] foo = {new Foo(), new Foo()};
Object o = foo;
// ...
Foo[] bar = (Foo[])o;
}https://stackoverflow.com/questions/1528148
复制相似问题