2016-05-27 22 views
2

JavaコードからC++コードへ多次元配列(Javaではshort[][]short int[][])を送信し、いくつかの共変を処理してから、Javaコードで配列を取得したいと考えています。SWIGでJavaとC++の間で多次元配列を渡す方法は?

1次元配列では問題ありません。

example.i:

%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" 

example.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; 
     } 
    } 


}; 

MainRunner.java

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"); 
     } 
     } 
} 

あなたはガブガブ飲むにmutlidimensionalの配列を処理する方法を知っていますか?

ありがとうございました!

+0

は 'のstdです::ベクトル 'オプション?物事をより簡単にする – Flexo

答えて

-1

おそらく、最も簡単な解決策になるはずですが、行と列に2つのパラメータを渡す必要があります。

事前に配列サイズを固定している場合は、パラメータでそのように宣言できます。

+0

私はあなたがそれをどうやってやるのかという質問をしていると思います – Flexo

0

私はあなたがこれを使いたい場合の種類を説明するためにヘッダファイルを作成しました。非正方形2D配列をサポートするには、出力関数の2つのサイズパラメータとしてwhがあります。

これは、C++ではなく、C言語をターゲットとする場合よりも少しシンプルです(しかし、JCALLxマクロの美しさはどちらの言語でも機能します)。 (注:C++を使用している場合は、代わりにstd::arrayまたはstd::vectorを適切に使用して、 とし、すべてのラッピングを無料で入手してください)。

#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" 

不規則な形状の作成から人々を防ぐために、そこに隠れてのassert(すなわち非矩形2Dアレイ)

は場所に私たちはその後、実行できるようであります。

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); 
    } 
} 
関連する問題