解析 SWIG 接口文件的结构属性

2024-05-27

这是我不久前问过的问题的延续。为通过参数返回的函数创建类型映射 https://stackoverflow.com/questions/12793973/create-a-typemap-for-a-function-that-returns-through-arguments

上一个问题中的接口文件如下:

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

任何帮助解决问题将不胜感激! 问候汉克

Part Two

1:一位开发人员对 void toUtf8 有这样的说法:

Hi Hank,

“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 中简单直观的东西:

  1. For off_t您可以使用:

    %apply int { off_t };
    

    告诉 SWIG 进行治疗off_t as int在爪哇。除非你期待,否则这可能有效off_t比 int 更大。对于一些常见的 typedef,SWIG 已经在库中提供了适当的映射,我有点惊讶 off_t 不是其中之一。

    (您还可以选择在接口文件中向 SWIG 显示 typedef,而不是使用%apply)

  2. 对于“简单”数组(即不是结构的数组)执行以下操作:

    %include <arrays_java.i> 
    

    足以生成直观的 Java 界面,例如添加导致int field_offsets[VRTTXT_FIELDS_MAX]被包装为public void setField_offsets(int[] value)以及相应的获取。在为 setter 生成的代码中,有一个测试来检查大小是否匹配 - 如果不匹配,则会在运行时抛出异常,因为 Java 中没有编译时数组大小的概念。

  3. 这个答案讨论了包裹FILE*来自爪哇 https://stackoverflow.com/questions/8320605/swig-configuration-to-handle-a-file-c-input-parameter-in-java/8325243#8325243。在这种情况下,最简单的解决方案是使用如下内容:

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

    它隐藏了自动设置/获取text_file而是公开一个接受字符串并调用的 setterfopen.

    您可以选择更复杂的实现,如链接答案中所示,仍然很明显,或者您可以使用%inline相反,提供创建的替代方法SWIGTYPE_p_FILE在爪哇。

  4. 对于结构数组,最简单的解决方案是使用%ignore and %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数组转换为结构数组)。

    一个更优雅的解决方案可能是编写一些扩展的东西AbstractList http://docs.oracle.com/javase/1.5.0/docs/api/java/util/AbstractList.html (using Java 代码类型映射 http://www.swig.org/Doc2.0/Java.html#Java_code_typemaps,取决于你到底想如何做到这一点)在Java中并通过你暴露的东西返回的代理%extend

  5. 同样的方法%extend可以与toUtf8 member:

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

    (我不确定这个字段的用法是否正确,但无论如何原则都适用)。

  6. 你的链接列表已经可以从Java“自然”地遍历,尽管再次提供一个实现的代理是可能/明智的(?)AbstractSequentialList http://docs.oracle.com/javase/1.5.0/docs/api/java/util/AbstractSequentialList.html.

  7. For the int这真的是一个enum你仍然可以使用正确的 Java 枚举 http://www.swig.org/Doc2.0/Java.html#Java_proper_enums_classes来表示它:

    %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 };
    

    (这里的顺序很重要——伪造的enum需要在之后发生%include,但类型映射和前向声明需要发生在它之前)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解析 SWIG 接口文件的结构属性 的相关文章

  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐