Swig typemap中的临时变量生成

时间:2014-07-07 15:11:12

标签: python c swig

我发现Swig无法生成在typemap中定义的一些临时变量。

问题在于: 我已经定义了一个类型图。

%define %bound_buffer_input(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE)
  (int res, Py_ssize_t size = 0, const void *buf = 0) {
  res = PyObject_AsReadBuffer($input, &buf, &size);
  if (res<0) {
    PyErr_Clear();
    %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
  }
  $1 = ($1_ltype) buf;
  $2 = ($2_ltype) size;
}
%enddef

它适用于2种情况:

%bound_buffer_input(const uint8_t* key, size_t keyLength);
%bound_buffer_input(void* buf, size_t length);

首先,它运作良好并生成正确的代码。但是对于第二个,它无法为函数生成正确的变量名称: void * MF_WriteOne(void * qry,int datatype,void * buf,size_t length);

代码swig生成:

 {
    res3 = PyObject_AsReadBuffer(obj2, &buf3, &size3);
    if (res3<0) {
      PyErr_Clear();
      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "MF_WriteOne" "', argument " "3"" of type '" "(void* buf, size_t length)""'");
    }
    arg3 = (void *) buf;
    arg4 = (size_t) size3;
  }

在第一行中,变量&#34; buf&#34;使用名称&#34; buf3&#34;正确生成,但对于第6行,变量名称不正确&#34; buf&#34;而不是&#34; buf3&#34;。

稍后我将名称从&#34; buf更改为buff&#34;并且发现变量都在正确的名称下。

为什么会发生这么奇怪的事情?

1 个答案:

答案 0 :(得分:1)

问题是你的typemap有一个名字冲突。传递给函数的变量名称为buf,变量名称(自动重命名)也为buf

SWIG正试图变得聪明并使用上下文正确的,但这不是你希望的行为。您可以通过以下几种方式解决此问题:

  1. 如您所述
  2. 重命名两个buf中的一个或两个
  3. 更改为宏指定的名称,但使用%apply仍然匹配buf作为参数名称:

    %module test
    
    %define %bound_buffer_input(TYPEMAP, SIZE)
    %typemap(in) (TYPEMAP, SIZE)
      (int res, Py_ssize_t size = 0, const void *buf = 0) {
      res = PyObject_AsReadBuffer($input, &buf, &size);
      if (res<0) {
        PyErr_Clear();
        %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
      }
      $1 = ($1_ltype) buf;
      $2 = ($2_ltype) size;
    }
    %enddef
    
    %bound_buffer_input(const uint8_t* key, size_t keyLength);
    %bound_buffer_input(void* buffer, size_t length);
    
    %apply (void* buffer, size_t length) { (void* buf, size_t length) };
    
    %inline %{
    void test1(const uint8_t* key, size_t keyLength) {}
    void test2(void* buf, size_t length) {}
    %}
    
  4. 使用typemap中的noblock=1手动自动重命名本地人,而不是临时的:

    %module test
    
    %define %bound_buffer_input(TYPEMAP, SIZE)
         %typemap(in,noblock=1) (TYPEMAP, SIZE) {
      int res$argnum;
      Py_ssize_t size$argnum = 0;
      const void *buf$argnum = 0;
      res$argnum = PyObject_AsReadBuffer($input, &buf$argnum, &size$argnum);
      if (res$argnum<0) {
        PyErr_Clear();
        %argument_fail(res$argnum, "(TYPEMAP, SIZE)", $symname, $argnum);
      }
      $1 = ($1_ltype) buf$argnum;
      $2 = ($2_ltype) size$argnum;
    }
    %enddef
    
    %bound_buffer_input(const uint8_t* key, size_t keyLength);
    %bound_buffer_input(void* buf, size_t length);
    
    %inline %{
    void test1(const uint8_t* key, size_t keyLength) {}
    void test2(void* buf, size_t length) {}
    %}
    
  5. 最后,除非你的目标是Python 2.6及更早版本,否则你应该use Python's newer memory views而不是