首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SWIG指针和Java数组

SWIG指针和Java数组
EN

Stack Overflow用户
提问于 2009-10-06 21:18:03
回答 3查看 3.7K关注 0票数 4

SWIG文档解释了C语言中的各种输入类型,比如:

代码语言:javascript
复制
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中接受一种类型的参数,如下所示:

代码语言:javascript
复制
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:中的返回类型:

代码语言:javascript
复制
Foo *spam5();
Foo &spam6();
Foo  spam7();

..。这三个函数都将返回一个指向某个Foo对象的指针,该指针将被分配给一个Java对象变量,最后一个函数需要分配一个值类型,Java垃圾回收将在释放时处理该值类型。

但是假设spam5()返回一个指向数组的指针。在Java中,我必须使用数组语义来访问各个元素,但我不认为我可以这样做:

代码语言:javascript
复制
Foo foo[] = spam5();

我甚至不认为编译器会接受(Foo[])的类型转换,那么这在SWIG中是如何工作的呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-10-06 21:40:57

这个问题没有简单或自动的解决方案。相信我,我找过了。

问题是SWIG不知道返回的数组应该有多大,所以它不能生成Java数组。您也不能将大小作为参数提供给函数(尽管可能是粗略的)-类型映射不会以这种方式工作。

在一般情况下,您必须编写另一个包装器函数,该函数接受一个C数组和一个长度作为输出参数,并使用类型映射将这两个参数转换为Java数组。或者,如果您不介意使用carrays.i,您可以跳过第二步,直接使用Java中的C数组。

票数 5
EN

Stack Overflow用户

发布于 2009-10-23 22:28:55

您可以直接使用JNI:

假设您想要检索一个xyz向量数组

代码语言:javascript
复制
public class demo{
  public native vecteur[] returnArray();

  ....
}

在swig wrap cxx文件中,添加将填充java vect数组的函数

代码语言:javascript
复制
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);
  }

最后是主类

代码语言:javascript
复制
// 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());

  }
}
票数 0
EN

Stack Overflow用户

发布于 2009-10-06 21:41:41

在java中,数组是一个对象,因此,如果spam5()返回Object,那么编译器将允许您将其转换为Foo的数组。这是有效的Java:

代码语言:javascript
复制
    class Bar {
        static class Foo {}
        Foo[] foo = {new Foo(), new Foo()};
        Object o = foo;
        // ...
        Foo[] bar = (Foo[])o;
    }
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1528148

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档