【问题标题】:SWIG void * parametersSWIG 无效 * 参数
【发布时间】:2013-08-07 16:53:29
【问题描述】:

我的 swig .i 文件中有两个结构(实际上来自第三方库),它们遵循这种形式:

typedef struct MY_STRUCT {
  void*       pParameter;
  unsigned long pLen;
} MY_STRUCT;
%extend MY_STRUCT
{
    MY_STRUCT()
    {
        MY_STRUCT *m= new MY_STRUCT();
        m->pParameter = NULL;
        m->pLen = 0;
        return m;
    }
}

typedef struct ANOTHER_STRUCT {
    char * another;
    unsigned long len;
} ANOTHER_STRUCT;
%extend ANOTHER_STRUCT
{
    ANOTHER_STRUCT()
    {
        ANOTHER_STRUCT *p= new ANOTHER_STRUCT();
        p->another = NULL;
        p->len = 0;
        return p;
    }
    unsigned long __len__()
    {
        return sizeof(ANOTHER_STRUCT);
    }
}

MY_STRUCT 中的 pParameter 是 void *,因为它可以是 char * 或指向结构的指针(例如 ANOTHER_STRUCT)。使用 %typemap(in) void* = char*; 处理 char * 映射很简单,但任何使用结构的尝试都会失败。以下是我希望在 Python 中看到的内容:

s = MY_STRUCT()
another = ANOTHER_STRUCT()
s.pParameter = another # this should pass the struct pointer
s.pParameter = "some string" # or a char pointer if this is provided

这可能吗?如果没有,是否需要声明一些辅助函数来分配指针值?

【问题讨论】:

  • 鉴于您使用了 new 关键字,我有点困惑为什么您需要将 %extend 用于构造函数,但这不是重点。

标签: python c swig


【解决方案1】:

您可以使用 SWIG 执行此操作。不过,您最终将编写fairly large if 来选择如何处理 Python 输入,具体取决于您要处理的类型数量。这是您需要的两个类型图的完整示例:

%module test

%typemap(in) void* pParameter (int res=0, void *other_struct=NULL) %{
  int len;
  res = SWIG_ConvertPtr($input, &other_struct, $descriptor(struct ANOTHER_STRUCT*), 0);
  if (SWIG_IsOK(res)) {
    fprintf(stderr, "struct\n");
    $1 = reinterpret_cast< ANOTHER_STRUCT * >(argp1);
    len = sizeof(ANOTHER_STRUCT);
  }
  else if (PyString_Check($input)) {
    $1 = PyString_AsString($input);
    len = strlen((const char*)$1);
    fprintf(stderr, "string\n");
  }
  //else if (...) {
  //}
  else {
    SWIG_exception_fail(SWIG_TypeError, "some more details, see special typemap variables docs for ideas");
  }
%}

%typemap(memberin) void* pParameter %{
  $1 = $input; //fobar $self
  $self->pLen = len;
%}

%inline %{
typedef struct MY_STRUCT {
  void*       pParameter;
  unsigned long pLen;
} MY_STRUCT;

typedef struct ANOTHER_STRUCT {
} ANOTHER_STRUCT;
%}

%extend MY_STRUCT
{
    MY_STRUCT()
    {
        MY_STRUCT *m= new MY_STRUCT;
        m->pParameter = NULL;
        m->pLen = 0;
        return m;
    }
}

在这里,in 类型映射采用 PyObject 并计算出如何处理它。它还将长度保存到局部变量中。

memberin 类型映射使用它来适当地设置void* 和长度。

您可能需要考虑使pLen 不可变(请参阅:%immutable),这样人们就不能随意更改该指针。您还需要仔细考虑此类类型映射的内存所有权语义,以避免泄漏或双重释放。

【讨论】:

  • 谢谢柔印,我会尽快检查的。
猜你喜欢
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多