问题描述
这是一个问题,我问了一段时间后的延续。 Create对于通过参数返回
this is a continuation of question I asked a while back. Create a typemap for a function that returns through arguments
在previous问题的接口文件如下:
In the previous question the interface file is as follows:
%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"
我现在要解决gaiaTextReaderPtr结构,它驻留在structs.h。
这个结构是在以下code的底部,虽然我已经包括别人都在它内部,以及给一个完整的图片。
I now have to resolve the gaiaTextReaderPtr struct, which resides in structs.h.This struct is at the bottom of the following code though I have included others that are within it as well to give a full picture.
我都强调与正在创建SWIG不透明数据类型行
I have underlined the lines with SWIG opaque datatypes being created
/** 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;
任何帮助将大大AP preciated进行解析!
问候汉克
Any help would greatly be appreciated for resolution!Regards Hank
第二部分
1 一个发展家伙是这样说的关于无效toUtf8:
Part Two
1: One of the development guys had this to say about void toUtf8:
汉克
一个无效*指针简直是一个普通的不透明的内存指针;它的
基本上是一个句柄。
a "void *" pointer simply is a generic opaque memory pointer; it's basically an handle.
在特定的语境无效* toUtf8引用内部结构
通过ICONV要求。引用的对象必须由创建
previous调用gaiaCreateUTF8Converter(),并预计会
通过调用gaiaFreeUTF8Converter()之前或之后销毁;每
来电gaiaFreeUTF8Converter()要求该指针传递作为
一个参数。
in the specific context "void *toUtf8" references the internal struct required by ICONV. the referenced object has to be created by a previous call to gaiaCreateUTF8Converter(), and is expected to be destroyed before or after by invoking gaiaFreeUTF8Converter(); each call to gaiaFreeUTF8Converter() requires this pointer to be passed as an argument.
在你的Java /痛饮角度来看,这仅仅是一个恒定值是
回传,准确地转发,因为它是。 (任何企图直接
变化,访问或取消引用此指针很容易导致一些
灾难==系统崩溃)
From your Java/SWIG perspective it simply is a constant value to be passed back and forward exactly as it is. (any attempt to directly change, access or dereferencing this pointer could easily lead to some disaster == system crash)
再见桑德罗
2 我有几个其他结构的,这是最后在gg_structs.h,是使用下面的有问题。
2: I have a couple of other structs, these are the last in gg_structs.h, that are having issues using the following.
/** COORDs mem-array */
double *Coords; /* X,Y [vertices] array */
因为我刚才放的时刻:
For the moment I have have just put:
%apply double[] {double *};
这已经清除它,但是我真的不知道,如果这是正确的。我应该单独针对阵列?其实我pretty确保它不正确只是看着它创建的类,它表明:
This has cleared it up, however I am not really sure if this is correctly. Should I be targeting the arrays individually? Actually I'm pretty sure it's incorrect just looked at the class it created and it shows :
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指数为使其正常工作?对于双我这样做:
Shouldn't this have an: int index for it to work correctly? For the double I did this:
%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代理。请问这是什么称其为动态代理?
3: I would be interested in hearing more about providing a proxy that implements AbstactSequentialList. Is this what is refer to as a Dynamic Proxy?
推荐答案
一个少数这些类型是很容易映射到Java中的一些简单而直观的:
A few of these types are quite easy to map onto something simple and intuitive in Java:
-
有关
off_t
你可以使用:
%apply int { off_t };
告诉痛饮治疗 off_t
为 INT
在Java中。这可能工作,除非你希望 off_t
比一个int更大。对于一些常见的typedef痛饮库中已经提供了合适的映射,我微微一惊off_t是不是其中之一。
to tell SWIG to treat off_t
as int
in Java. That probably works unless you're expecting off_t
to be bigger than an int. For some common typedefs SWIG supplies an appropriate mapping in the library already, I'm slightly surprised off_t isn't one of them.
(你也可以选择显示痛饮在接口文件的类型定义,而不是使用%适用
)
(You could also choose to show SWIG a typedef in your interface file instead of using %apply
)
有关简单的数组(即不属于一个结构的东西阵列)这样做的:
For the "simple" arrays (i.e. arrays of things which aren't a struct) doing:
%include <arrays_java.i>
足以让产生一个直观的Java接口,例如添加将导致 INT field_offsets [VRTTXT_FIELDS_MAX]
来包装为公共无效setField_offsets( INT []值)
和相应的GET。内部生成的code的二传手有一个测试,以检查大小相匹配 - 这在运行时将抛出一个异常,如果他们不这样做,因为没有在Java的编译时数组大小的概念
is sufficient to get an intuitive Java interface generated, for example adding that causes int field_offsets[VRTTXT_FIELDS_MAX]
to be wrapped as public void setField_offsets(int[] value)
and a corresponding get. Inside the generated code for the setter there is a test to check the sizes match - this will throw an exception at runtime if they don't, since there's no concept of compile time array size in Java.
这答案讨论wrapping FILE *
从Java 。在这种情况下最简单的解决办法是使用这样的:
This answer discussed wrapping FILE*
from Java. In this instance the simplest solution would be to use something like:
%ignore text_file
%include "header.h"
%extend gaiaTextReader {
void setTextFile(const char *fn) {
$self->text_file = fopen(fn, "r");
}
}
这隐藏了自动设置/获取为 text_file
,而是暴露了一个二传手,它接受一个字符串,并调用的fopen
。
which hides the automatic set/gets for text_file
and instead exposes a setter that takes a string and calls fopen
.
您可以选择更复杂的实现作为链接的答案仍然很明显,或者你可以使用%直列
,而不是提供创建 SWIGTYPE_p_FILE Java编写的。
You could choose the more complex implementation as in the linked answer still obviously, or you could use %inline
instead to provide alternative ways of creating a SWIGTYPE_p_FILE
in Java.
至于结构的阵列最简单的办法是使用%忽略
和%延长
再次,例如:为列
是这样的:
With regards to the arrays of structs the simplest solution would be to use %ignore
and %extend
again, e.g. for columns
this is:
%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调用从对象
数组结构的阵列做副本里面会涉及很多)更简单。
This is simpler than writing a typemap (which would involve a lot of JNI calls to do the copy from an Object
array into the array of structs).
一个更优雅的解决方案可能是写的东西延伸的(使用的,这取决于你想究竟是如何做到这一点)在Java中,并且通过东西回来你已经暴露代理延长%
A more elegant solution might be to write something that extends AbstractList
(using Java code typemaps, depending on how exactly you wanted to do it) in Java and proxies that back via something you've exposed in %extend
同样的方法%延长
可采取与 toUtf8
成员:
The same approach to %extend
can be taken with the toUtf8
member:
%ignore toUtf8;
%include "header.h"
%extend gaiaTextReader {
void setToUtf8(const char *from) {
$self->toUtf8 = iconv_open("tocode", from);
}
}
(我不知道我有这个字段的用法完全正确的,但原则适用不管)。
(I'm not sure I've got the usage of this field quite right, but the principle applies regardless).
您链表可以被穿越自然地从Java虽然已经再次有可能/明智的(?),以提供一个代理实现的。
Your linked list can be traversed "naturally" from Java already although again it would be possible/sensible(?) to provide a proxy that implements AbstractSequentialList
.
对于 INT
这是一个真正的枚举
你仍然可以使用的来重新present是:
For the int
that's really an enum
you could still use proper Java enums to represent it:
%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 };
(此处的顺序很重要 - 伪造的枚举
需要%包含
,但typemaps发生后,和前需要申报之前发生)。
(The order here is important - the faked enum
needs to happen after the %include
, but the typemaps and the forward declaration need to happen before it).
这篇关于为解决SWIG接口文件结构的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!