有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在java与C++之间使用SWIG传递多维数组?

java java java C++代码中的多维数组(^ {CD1>},^ {CD2>})从Java代码发送到C++代码,处理一些合谋,然后用Java代码返回数组p>

它适用于一维数组

例如。我:

%module example

%{
#include <iostream>
#include "example.h"
%}

%typemap(jtype) short int values[] "short[]"
%typemap(jstype) short int[] "short[]"
%typemap(javain) short int values[] "$javainput"
%typemap(jni) short int values[] "jshortArray"
%typemap(in) short int values[] {
  jboolean isCopy;
  $1 = JCALL2(GetShortArrayElements, jenv, $input, &isCopy);
}

%typemap(in,numinputs=0,noblock=1) int *data_len {
   int temp_len;
   $1 = &temp_len;
}


%typemap(jstype) const short int *CPPtoJava "short[]"
%typemap(jtype) const short int *CPPtoJava "short[]"
%typemap(jni) const short int *CPPtoJava "jshortArray"

%typemap(javaout) const short int *CPPtoJava {
  return $jnicall;
}


%typemap(out) const short int *CPPtoJava {
  $result = JCALL1(NewShortArray, jenv, temp_len);
  JCALL4(SetShortArrayRegion, jenv, $result, 0, temp_len, $1);
}



%include "example.h"

例如。h:

class Test
{
public:

    short int* data;
    size_t l;

    void JavaToCPP(short int values[], size_t len) {
        this->l = len;
        this->data = values;
    }

    const short int *CPPtoJava(int *data_len){
        *data_len = this->l ;
        return this->data;
    }

    void process(){
        for(int i = 0 ; i< this->l ; i++){
            this->data[i] = i;
        }
    }


};

主要负责人。爪哇

public class MainRunner {
    public static void main(String[] argv) {
        System.load("/path/to/../libexample.so");

        short in[] = {0,0,0};
        System.out.println("\nInput : ");
        for (int i = 0; i < in.length; ++i) {
              System.out.print(in[i] + "\t");
        }


        Test t = new Test(); 
        t.JavaToCPP(in,(long)in.length);
        t.process();


        short[] out = t.CPPtoJava();
        System.out.println("\n\nOutput : ");
        for (int i = 0; i < out.length; ++i) {
              System.out.print(out[i] + "\t");
        }
      }
}

你知道如何在Swig中处理多维数组吗

谢谢你的帮助


共 (2) 个答案

  1. # 1 楼答案

    您可能需要为行和列传递两个参数,这应该是最简单的解决方案

    如果事先有固定的数组大小,可以在参数中以这种方式声明

  2. # 2 楼答案

    我创建了一个头文件来说明您可能想要使用它的情况。为了支持非方形2D数组,它将wh作为输出函数的两个大小参数

    比你的示例情况稍微简单,以C为目标,而不是C++(但是JCLAX宏的美意是它们为任何语言工作)。(NB:如果您使用C++,则只使用^ {CD3}}或^ {CD4}}为宜。 取而代之的是免费获得所有包装)

    #include <stdlib.h>
    #include <string.h>
    
    short **CPPtoJava(size_t *w, size_t *h) {
      *w = 3;
      *h = 4;
      short **data = malloc(sizeof(short*) * *w);
      for (size_t i = 0; i < *w ; ++i) {
        data[i] = malloc(sizeof(short) * *h);
        for (size_t j = 0; j < *h; ++j) {
          data[i][j] = (1+i)*(1+j);
        }
      }
      return data;
    }
    
    void JavaToCPP(short **values, size_t w, size_t h) {
      for (size_t i = 0; i < w; ++i) {
        for (size_t j = 0; j < h; ++j) {
          printf("(%zu, %zu): %d\n", i, j, (int)values[i][j]);
        }
      }
    }
    

    有了它,我们可以编写一些类型映射来封送Java内外的数据。它们与1D情况没有太大不同,只是我们设置并构建了N个1D数组和1个数组

    %module test
    
    %{
    #include "test.h"
    #include <assert.h>
    %}
    
    // For the outputs
    %typemap(jni) short ** "jobjectArray"
    %typemap(jstype) short ** "short[][]"
    %typemap(jtype) short ** "short[][]"
    %typemap(javaout) short ** {
      return $jnicall;
    }
    %typemap(in,numinputs=0) size_t *w %{
      size_t w=0;
      $1 = &w;  
    %}
    %typemap(in,numinputs=0) size_t *h %{
      size_t h=0;
      $1 = &h;
    %}
    %typemap(out) short ** {
      $result = JCALL3(NewObjectArray, jenv, w, JCALL1(FindClass, jenv, "[S"), NULL);
      for (size_t i = 0; i < w; ++i) {
        jshortArray cur = JCALL1(NewShortArray, jenv, h);
        JCALL4(SetShortArrayRegion, jenv, cur, 0, h, $1[i]);
        JCALL3(SetObjectArrayElement, jenv, $result, i, cur);
      }
      free(result); // Since I called malloc this is needed
    }
    
    
    // For the inputs
    
    %typemap(jni) (short **values, size_t w, size_t h) "jobjectArray"
    %typemap(jstype) (short **values, size_t w, size_t h) "short[][]"
    %typemap(jtype) (short **values, size_t w, size_t h) "short[][]"
    %typemap(javain) (short **values, size_t w, size_t h) "$javainput"
    %typemap(in,numinputs=1,noblock=1) (short **values, size_t w, size_t h) {
      $2 = JCALL1(GetArrayLength, jenv, $input);
      $1 = alloca(sizeof(short*) * $2); // Or maybe not on stack if you prefer?
      $3 = 0;
      if ($2 > 0) {
        jshortArray dim1 = JCALL2(GetObjectArrayElement, jenv, $input, 0);
        $3 = JCALL1(GetArrayLength, jenv, dim1);
      }
    
      for (size_t i = 0; i < $2; ++i) {
        jshortArray cur = JCALL2(GetObjectArrayElement, jenv, $input, i);
        assert((size_t)JCALL1(GetArrayLength, jenv, cur) == $3); // TODO: handle error
        $1[i] = JCALL2(GetShortArrayElements, jenv, cur, NULL);
      }
    }
    %typemap(freearg) (short **values, size_t w, size_t h) {
      for (size_t i = 0; i < $2; ++i) {
        jshortArray cur = JCALL2(GetObjectArrayElement, jenv, $input, i);
        JCALL3(ReleaseShortArrayElements, jenv, cur, $1[i], JNI_ABORT);
      }
    }
    
    %include "test.h"
    

    有一个断言隐藏在那里,以防止人们创建不规则形状(即非矩形二维阵列)

    有了这些,我们就可以运行:

    import java.util.Arrays;
    
    public class run {
      private static void print(short[][] arr) {
        for (int i = 0; i < arr.length; ++i) {
          System.out.println(Arrays.toString(arr[i]));
        }
      }
    
      public static void main(String[] argv) {
        System.loadLibrary("test");
        short[][] r1 = test.CPPtoJava();
        print(r1);
        test.JavaToCPP(r1);
      }
    }