使用痛饮python中嵌套结构数组访问 [英] nested structure array access in python using SWIG

查看:435
本文介绍了使用痛饮python中嵌套结构数组访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直无法弄清楚如何访问数组元素子状态在下面的嵌套结构。我似乎能够看到的第一个元素,但并不了解如何强制索引,例如,作为列表

任何帮助很多AP preciated。

status.h

  //数据类型
字符的typedef CHAR; // 8位签约
typedef的短短; // 16位签署
长期的typedef长; // 32位签署
的typedef unsigned char型UCHAR; // 8位无符号
的typedef无符号短USHORT; // 16位usigned#定义FUNC_TYPE //建于C,离开参考为C
#定义DLL_API的extern FUNC_TYPE __declspec(dllimport的)//子状态数据
typedef结构
{
    龙某某;
    LONG ABC;
} SUB_STATUS;
//状态信息
typedef结构
{
    UCHAR QRS;
    UCHAR TUV;
    SUB_STATUS子状态[4];
    LONG WXY;
} 状态;DLL_API的getStatus短(STATUS *状态);

status.i

 %模块状态
 %{
 / *包括在包装code *页眉/
 #包括status.h
 %} / *解析头文件来生成包装* /
 %有窗户向
 %包括typemaps.i
 %包括status.h


解决方案

你可以用这个头,而无需修改它买做这样的事情:

 %模块状态%不变;
%一致 %{
模板< typename的类型,为size_t N'GT;
结构wrapped_array {
  类型(安培;数据)[N];
  wrapped_array(类型(安培;数据)[N]):数据(数据){}
};
%}
%可变的;%{
#包括status.h
%}%包括typemaps.i
%包括std_except.i//只能暴露缩减的状态,没有数组:
typedef结构
{
    UCHAR QRS;
    UCHAR TUV;
    LONG WXY;
} 状态;%扩展wrapped_array {
  内联为size_t __len __()const的{返回N; }  内联常量类型和放大器; __getitem __(为size_t我)const的掷(的std :: out_of_range){
    如果(ⅰ> = N || I&小于0)
      抛出std :: out_of_range(越界访问);
    返回$自我>数据[I]
  }  内嵌无效__setitem __(为size_t我,const的类型和放大器; 5)掷(的std :: out_of_range){
    如果(ⅰ> = N || I&小于0)
      抛出std :: out_of_range(越界访问);
    $自>数据[I] = V;
  }
}%模板(SubStatusArray)wrapped_array&下; SUB_STATUS,4取代;//隐藏在我们的帮助真正的数组%扩展状态{
  wrapped_array&所述; SUB_STATUS,4为H. getSubStatus(){
    返回wrapped_array&下; SUB_STATUS,4为H.($自>子状态);
  }
}%忽略状态; //我们指定了该包装的替代方式
%包括status.h

这是基本相同 href=\"http://stackoverflow.com/a/8203652/168175\">我的答案,但代替修改标题使用 wrapped_array 中,我们使用%忽略来告诉我们SWIG将提供我们自己的状态为它换行。 (这是完全合法的,在痛饮生成的包装仍然将使用status.h真正的定义)

我们注入这种改变定义中的 getSubStatus(),它返回充当代理到真正的数组中的状态。此代理反过来用品 __的GetItem __ __ setitem __ __ LEN __ 的Python将使用下标运算符。

有可能是一个办法在Python正确做到这一点,而无需在 getSubStatus(),使得SWIG设置 __ swi​​g_setmethods __ [子状态] __ swi​​g_getmethods __ [子状态] 恰当,但我不知道把我的头顶部如何使痛饮蟒蛇做到这一点。

如果你使用C,不使用C ++你要删除的模板赞成只是一个普通的结构和使用,而不是一个参考指针阵列

I haven't been able to figure out how to access the array elements SubStatus in the following nested structure. I do seem to be able to see the first element, but don't understand how to force indexing, e.g., as a list.

Any help is much appreciated.

status.h:

// Data Types
typedef char           CHAR;   // 8 bits signed
typedef short          SHORT;  // 16 bits signed
typedef long           LONG;   // 32 bits signed
typedef unsigned char  UCHAR;  // 8 bits unsigned
typedef unsigned short USHORT; // 16 bits usigned

#define FUNC_TYPE       // built in C, leave reference as C
#define DLL_API extern FUNC_TYPE __declspec(dllimport)

// Sub Status Data
typedef struct
{
    LONG  xyz;                              
    LONG  abc;                                           
} SUB_STATUS;


// Status Info
typedef struct
{
    UCHAR  qrs;             
    UCHAR  tuv;             
    SUB_STATUS SubStatus[4];     
    LONG   wxy;     
} STATUS;

DLL_API  SHORT  GetStatus( STATUS *Status );

status.i

%module status
 %{
 /* Includes the header in the wrapper code */
 #include "status.h"
 %}

 /* Parse the header file to generate wrappers */
 %include "windows.i"
 %include "typemaps.i" 
 %include "status.h"

解决方案

You can wrap this header without having to modify it buy doing something like:

%module status

%immutable;
%inline %{
template <typename Type, size_t N>
struct wrapped_array {
  Type (&data)[N];
  wrapped_array(Type (&data)[N]) : data(data) { }
};
%}
%mutable;

%{
#include "status.h"
%}

%include "typemaps.i"
%include "std_except.i"

// Only expose a reduced STATUS, without the Array:
typedef struct
{
    UCHAR  qrs;
    UCHAR  tuv;
    LONG   wxy;
} STATUS;

%extend wrapped_array {
  inline size_t __len__() const { return N; }

  inline const Type& __getitem__(size_t i) const throw(std::out_of_range) {
    if (i >= N || i < 0)
      throw std::out_of_range("out of bounds access");
    return $self->data[i];
  }

  inline void __setitem__(size_t i, const Type& v) throw(std::out_of_range) {
    if (i >= N || i < 0)
      throw std::out_of_range("out of bounds access");
    $self->data[i] = v;
  }
}

%template (SubStatusArray) wrapped_array<SUB_STATUS,4>;

// Hide the real array in our helper

%extend STATUS {
  wrapped_array<SUB_STATUS,4> getSubStatus() {
    return wrapped_array<SUB_STATUS,4>($self->SubStatus);
  }
}

%ignore STATUS; // We've specified an alternative way of wrapping this
%include "status.h"

This is basically the same as my answer here, but instead of modifying the header to use the wrapped_array, we've used %ignore to tell SWIG we will supply our own definition of STATUS for it to wrap. (This is perfectly legal, the SWIG generated wrapper will still use the real definition from status.h)

We inject into this altered definition a getSubStatus(), which returns an object that acts as a proxy to the real array in STATUS. This proxy in turn supplies __getitem__, __setitem__ and __len__ that python looks for to use the subscript operator.

There might be a way to do this properly in Python without needing the getSubStatus(), making SWIG set __swig_setmethods__["SubStatus"] and __swig_getmethods__["SubStatus"] appropriately, but I'm not sure off the top of my head how to make SWIG python do that.

If you're using C, not using C++ you'll want to drop the template in favour of just a plain struct and use a pointer instead of a reference to an array.

这篇关于使用痛饮python中嵌套结构数组访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆