这是我前一段时间问过的问题的延续。为通过参数返回的函数创建类型图
在上一个问题中,接口文件如下:
%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不透明数据类型下划线
/** 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;
任何帮助将不胜感激解决!关于汉克
第二部分
1: 一位开发人员曾这样说过toUtf8无效:
嗨,汉克, “ void *”指针只是一个通用的不透明内存指针;它基本上是一个句柄。 在特定上下文中,“ void * toUtf8”引用了ICONV所需的内部结构。被引用的对象必须通过先前对gaiaCreateUTF8Converter()的调用来创建,并且期望在调用gaiaFreeUTF8Converter()之前或之后被销毁;每次对gaiaFreeUTF8Converter()的调用都需要将此指针作为参数传递。 从Java / SWIG角度来看,它只是一个常量,可以照原样传递。(任何直接更改,访问或取消引用此指针的尝试都很容易导致灾难==系统崩溃) 再见桑德罗
嗨,汉克,
“ 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的代理的信息。这就是所谓的动态代理吗?
这些类型中的一些很容易映射到Java中简单直观的对象上:
off_t
%apply int { off_t };
告诉SWIG将其off_t视为intJava。除非您期望off_t大于一个int,否则这可能会起作用。对于某些常见的typedef,SWIG已经在库中提供了适当的映射,我有点惊讶off_t不是其中之一。
int
(您也可以选择在界面文件中显示SWIG typedef,而不是使用%apply)
%apply
%include <arrays_java.i>
足以生成一个直观的Java界面,例如添加导致int field_offsets[VRTTXT_FIELDS_MAX]被包装为as public void setField_offsets(int[] value)和相应的get的添加。在为setter生成的代码中,有一个检查大小匹配的测试- 如果大小不匹配,则会在运行时抛出异常,因为Java中没有编译时间数组大小的概念。
int field_offsets[VRTTXT_FIELDS_MAX]
public void setField_offsets(int[] value)
FILE*
%ignore text_file
%include “header.h” %extend gaiaTextReader { void setTextFile(const char *fn) { $self->text_file = fopen(fn, “r”); } }
它隐藏自动设置/获取text_file,而是公开一个带字符串并调用的setter fopen。
text_file
fopen
您可以选择仍然很明显的链接答案中所示的更复杂的实现,或者可以使用它%inline来提供使用SWIGTYPE_p_FILEJava 创建的替代方法。
%inline
SWIGTYPE_p_FILE
至于结构的阵列,最简单的办法是使用%ignore和%extend再次,例如对于columns这是:
%ignore
%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; } }
这比编写类型映射表简单(后者将涉及很多JNI调用,以从Object数组复制到结构数组)。
Object
一个更优雅的解决方案可能是在Java中编写扩展的内容AbstractList(使用Java代码类型映射,具体取决于您要执行的操作),然后通过在Java中公开的内容来返回代理%extend
AbstractList
成员%extend可以采用相同的方法toUtf8:
toUtf8
%ignore toUtf8;
%extend gaiaTextReader { void setToUtf8(const char *from) { $self->toUtf8 = iconv_open(“tocode”, from); } }
(我不确定该字段的用法是否正确,但是无论如何都适用该原则)。
您的链表可以从Java中“自然地”遍历,尽管有可能/明智的(?)提供实现的代理AbstractSequentialList。
AbstractSequentialList
因为int确实如此,enum您仍然可以使用适当的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)”
enum Type { TEXT=VRTTXT_TEXT, INTEGER=VRTTXT_INTEGER, DOUBLE=VRTTXT_DOUBLE, NONE=VRTTXT_NULL };
(这里的顺序很重要-伪造的enum需要发生在之后%include,但是类型映射和前向声明需要发生在它之前)。
%include