0

これは私がしばらく前に尋ねた質問の続きです。引数を返す関数の型マップを作成する

前の質問では、インターフェイス ファイルは次のとおりです。

%module test

%{
#include "header.h"
%}

%inline %{
  %immutable;
  struct FieldFetch {
    int status;
    int type;
    char *value;
  };
  %mutable;

  struct FieldFetch gaiaTextReaderFetchField(gaiaTextReaderPtr reader, int field_num) {
    struct FieldFetch result;
    result.status = gaiaTextReaderFetchField(reader, field_num, &result.type, &result.value);
    return result;
  }
%}

%ignore gaiaTextReaderFetchField;
%include "header.h"

次に、structs.h にある gaiaTextReaderPtr 構造体を解決する必要があります。この構造体は次のコードの一番下にありますが、全体像を示すためにその中に他の構造体も含めました。

SWIG opaque データ型が作成されている行に下線を引きました

/** Virtual Text driver: MAX number of fields */
#define VRTTXT_FIELDS_MAX   65535
/** Virtual Text driver: MAX block size (in bytes) */
#define VRTTXT_BLOCK_MAX 65535

/** Virtual Text driver: TEXT value */
#define VRTTXT_TEXT     1
/** Virtual Text driver: INTEGER value */
#define VRTTXT_INTEGER  2
/** Virtual Text driver: DOUBLE value */
#define VRTTXT_DOUBLE   3
/** Virtual Text driver: NULL value */
#define VRTTXT_NULL 4


/**
 Container for Virtual Text record (line)
 */
    struct vrttxt_line
    {
/* a struct representing a full LINE (aka Record) */
/** current offset (parsing) */
    off_t offset;
//__^________________________________________________________SWIGTYPE_p_off_t
/** line length (in bytes) */
    int len;
/** array of field offsets (where each field starts) */
    int field_offsets[VRTTXT_FIELDS_MAX];
//__^________________________________________________________SWIGTYPE_p_int
/** number of field into the record */
    int num_fields;
/** validity flag */
    int error;
    };

/**
 Container for Virtual Text record (line) offsets 
 */
    struct vrttxt_row
    {
/* a struct storing Row offsets */
/** Line Number */
    int line_no;
/** start offset */
    off_t offset;
//__^________________________________________________________SWIGTYPE_p_off_t
/** record (line) length (in bytes) */
    int len;
/** number of fields into this record */
    int num_fields;
    };

/**
 Container for Virtual Text block of records
 */
    struct vrttxt_row_block
    {
/*
/ for efficiency sake, individual Row offsets 
/ are grouped in reasonably sized blocks
*/
/** array of records [lines] */
    struct vrttxt_row rows[VRTTXT_BLOCK_MAX];
/** number of records into the array */
    int num_rows;
/** min Line Number */
    int min_line_no;
/** max Line Number */
    int max_line_no;
/** pointer to next item [linked list] */
    struct vrttxt_row_block *next;
    };

/** 
 Container for Virtual Text column (field) header
 */
    struct vrttxt_column_header
    {
/* a struct representing a Column (aka Field) header */
/** column name */
    char *name;
/** data type: one of GAIA_NULL_VALUE, GAIA_INT_VALUE, GAIA_DOUBLE_VALUE, GAIA_TEXT_VALUE */
    int type;
    };

/**
 Container for Virtual Text file handling
 */
    typedef struct vrttxt_reader
    {
/* the main TXT-Reader struct */
/** array of columns (fields) */
    struct vrttxt_column_header columns[VRTTXT_FIELDS_MAX];
/** FILE handle */
    FILE *text_file;
//__^________________________________________________________SWIGTYPE_p_FILE
/** handle to ICONV converter object */
    void *toUtf8;       /* the UTF-8 ICONV converter */
//__^________________________________________________________SWIGTYPE_p_void
/** field separator character */
    char field_separator;
/** text separator character (quote) */
    char text_separator;
/** decimal separator */
    char decimal_separator;
/** TRUE if the first line contains column names */
    int first_line_titles;
/** validity flag */
    int error;
/** pointer to first block of records [linked list] */
    struct vrttxt_row_block *first;
/** pointer to last block of records [linked list] */
    struct vrttxt_row_block *last;
/** array of pointers to individual records [lines] */
    struct vrttxt_row **rows;
//__^________________________________________________________SWIGTYPE_p_p_vrttxt_row
/** number of records */
    int num_rows;
/** current Line Number */
    int line_no;
/** max number of columns (fields) */
    int max_fields;
/** current buffer size */
    int current_buf_sz;
/** current buffer offset [parsing] */
    int current_buf_off;
/** I/O buffer */
    char *line_buffer;
/** current field buffer */
    char *field_buffer;
/** array of field offsets [current record] */
    int field_offsets[VRTTXT_FIELDS_MAX];
//__^________________________________________________________SWIGTYPE_p_int
/** array of field lengths [current record] */
    int field_lens[VRTTXT_FIELDS_MAX];
//__^________________________________________________________SWIGTYPE_p_int
/** max field [current record] */
    int max_current_field;
/** current record [line] ready for parsing */
    int current_line_ready;
    } gaiaTextReader;
/**
 Typedef for Virtual Text file handling structure

 \sa gaiaTextReader
 */
    typedef gaiaTextReader *gaiaTextReaderPtr;

解決のためにどんな助けも大歓迎です!よろしくハンク


パート 2

1:開発担当者の 1 人が void toUtf8 について次のように述べています。

こんにちはハンク、

「void *」ポインターは、単に一般的な不透明なメモリポインターです。基本的にハンドルです。

特定のコンテキストでは、「void *toUtf8」は、ICONV が必要とする内部構造体を参照します。参照されるオブジェクトは、gaiaCreateUTF8Converter() への以前の呼び出しによって作成される必要があり、gaiaFreeUTF8Converter() を呼び出す前または後に破棄されることが期待されます。gaiaFreeUTF8Converter() を呼び出すたびに、このポインタを引数として渡す必要があります。

Java/SWIG の観点からすると、これは単純に、そのまま正確にやり取りされる定数値です。(このポインターを直接変更、アクセス、または逆参照しようとすると、簡単に災害 == システム クラッシュが発生する可能性があります)

さようならサンドロ

2: 他にもいくつかの構造体があります。これらはgg_structs.hの最後のもので、次の使用に問題があります。

/** COORDs mem-array */
double *Coords;               /* X,Y [vertices] array */

今のところ、私はちょうど入れました:

%apply double[] {double *};

これで解決しましたが、これが正しいかどうかはわかりません。アレイを個別にターゲットにする必要がありますか? 実際、それが作成したクラスを見て、それが示しているのは間違っていると確信しています:

  public void setCoords(double[] value) {
    gg_structsJNI.gaiaLinestring_Coords_set(swigCPtr, this, value);
  }

  public double[] getCoords() {
    return gg_structsJNI.gaiaLinestring_Coords_get(swigCPtr, this);
  }

正しく機能するために、これには : int インデックスが必要ではありませんか? ダブルの場合、私はこれを行いました:

%ignore Coords;
%include "gg_structs.h"

%extend gaiaLinestring {
  void setCoords(int index, double value) {
    $self->Coords[index] = value;
  }

  double getCoords(int index) {
    return $self->Coords + index;
  }
}

3: AbstactSequentialList を実装するプロキシの提供について詳しく知りたいです。これは動的プロキシと呼ばれるものですか?

4

1 に答える 1

1

これらの型のいくつかは、Java の単純で直感的なものに非常に簡単にマップできます。

  1. あなたが使用するoff_tことができます:

    %apply int { off_t };
    

    SWIGにJavaのように扱うoff_tように指示intします。off_tintよりも大きいと予想しない限り、おそらくうまくいきます。一部の一般的な typedef については、SWIG が既にライブラリで適切なマッピングを提供していますが、off_t がそれらの 1 つではないことに少し驚いています。

    (使用する代わりに、インターフェイス ファイルで SWIG に typedef を表示することもできます%apply)

  2. 「単純な」配列 (つまり、構造体ではないものの配列) の場合:

    %include <arrays_java.i> 
    

    int field_offsets[VRTTXT_FIELDS_MAX]生成さ れた直観的な Java インターフェイスを取得するのに十分public void setField_offsets(int[] value)です。セッター用に生成されたコード内には、サイズが一致することを確認するテストがあります。Java にはコンパイル時の配列サイズの概念がないため、サイズが一致しない場合は実行時に例外がスローされます。

  3. この回答はJava からのラッピングFILE*について説明しました。この場合、最も簡単な解決策は次のようなものを使用することです。

    %ignore text_file
    %include "header.h"
    %extend gaiaTextReader {
      void setTextFile(const char *fn) {
        $self->text_file = fopen(fn, "r");
      }
    }
    

    の自動設定/取得を非表示にしtext_file、代わりに文字列を受け取って を呼び出すセッターを公開しますfopen

    リンクされた回答のように、より複雑な実装を選択することも、代わりに Java%inlineで作成する別の方法を提供するために使用することもできます。SWIGTYPE_p_FILE

  4. 構造体の配列に関しては、最も簡単な解決策は%ignoreandを使用することです。%extendたとえば、columnsこれは次のとおりです。

    %ignore columns;    
    %include "header.h"
    
    %extend gaiaTextReader {
      struct vrttxt_column_header *getColumn(int i) {
        return $self->columns + i;
      }
    
      void setColumn(struct vrttxt_column_header *c, int i) {
        $self->columns[i] = *c;
      }
    }
    

    これは、typemap を記述するよりも簡単です (Object配列から構造体の配列へのコピーを行うために、多くの JNI 呼び出しが必要になります)。

    よりエレガントな解決策は、Java で拡張するものAbstractList( Java コード typemapsを使用して、正確にどのように実行したいかによって異なります) と、公開したものを介して戻るプロキシを作成することです。%extend

  5. メンバーに対しても同じアプローチを%extend使用できます。toUtf8

    %ignore toUtf8;
    %include "header.h"
    
    %extend gaiaTextReader {
      void setToUtf8(const char *from) {
        $self->toUtf8 = iconv_open("tocode", from);
      }
    }
    

    (このフィールドの使い方が正しいかどうかはわかりませんが、原則は関係なく適用されます)。

  6. リンクされたリストは、すでに Java から「自然に」トラバースできますが、AbstractSequentialList.

  7. これはint実際には、適切な Java 列挙型を使用してそれを表すことenumができます。

    %include <enums.swg>
    %javaconst(1);
    
    enum Type;
    %typemap(jstype) int type "$typemap(jstype,enum Type)"
    %typemap(javain) int type "$typemap(javain,enum Type)"
    
    %include "header.h"
    
    enum Type { TEXT=VRTTXT_TEXT,
                INTEGER=VRTTXT_INTEGER,
                DOUBLE=VRTTXT_DOUBLE,
                NONE=VRTTXT_NULL };
    

    (ここでの順序は重要です。fakedenumは の後に発生する必要があります%includeが、typemaps と forward 宣言はその前に発生する必要があります)。

于 2013-01-05T10:55:37.150 に答える