如何使用静态变量和自定义 getter 和 setter 在 SWIG 中扩展结构?

Posted

技术标签:

【中文标题】如何使用静态变量和自定义 getter 和 setter 在 SWIG 中扩展结构?【英文标题】:How to extend a struct in SWIG with a static variable, with a custom getter and setter? 【发布时间】:2017-03-14 10:54:43 【问题描述】:

我想包装一个结构的静态成员变量,以便在从 Python 读取或写入它时,在 C++ 端调用自定义 get/set 函数。以下适用于非静态变量。这是foo.h

#ifndef FOO_H
#define FOO_H

#include <iostream>

struct Foo

  static int bar()  std::cout << "Foo::bar()\n"; return 0; 
;

#endif

foo.i 如下所示:

%module foo
%
  #include "foo.h"
%

struct Foo

;

%extend Foo 
  int i;


%
  int Foo_i_get(Foo* obj) 
    return Foo::bar();
  
  void Foo_i_set(Foo* obj, int i) 
%

这种工作,在 Python 中我可以做到:

import foo
f = foo.Foo()
f.i

这会触发 Foo::bar() 被调用。我想要实现的是具有相同行为的以下内容:

import foo
foo.Foo.i

这不起作用,因为i 不是类属性。 我天真地尝试在.i 文件中更改以下内容:

%extend Foo 
  static int i;

这会在 SWIG 生成的以下包装器代码中产生编译错误:

SWIGINTERN PyObject *Swig_var_Foo_i_get(void) 
  PyObject *pyobj = 0;

  pyobj = SWIG_From_int((int)(Foo::i));
  return pyobj;

这是g++给出的错误信息:

foo_wrap.c: In function ‘PyObject* Swig_var_Foo_i_get()’:
foo_wrap.c:3208:31: error: ‘i’ is not a member of ‘Foo’
    pyobj = SWIG_From_int((int)(Foo::i));

所以显然这不是正确的方法。如何使用静态变量、自定义 setter 和 getter 扩展结构?

【问题讨论】:

即使没有%extend SWIG 实际上也不会使类的静态成员可以通过foo.Foo.i 语法访问。我敢肯定,我们可以通过一些解决方法来做一些事情,但这不会是微不足道的。 【参考方案1】:

这可能有效:foo.i 如下所示:

%module foo
%
  #include "foo.h"
%

%include "foo.h"

%extend Foo 
  int get_i() return Foo::bar(); 
  %pythoncode %
     i = property(get_i)
  %

【讨论】:

很久以前我需要这个,我不确定我最终如何以及是否找到了解决方案。我会记下并检查我是如何解决的;以及您的方法是否有效,感谢您迟来的回答!

以上是关于如何使用静态变量和自定义 getter 和 setter 在 SWIG 中扩展结构?的主要内容,如果未能解决你的问题,请参考以下文章

getter和setter方法

导航栏高度和自定义按钮

Java中如何调用函数和自定义函数

java里的静态变量是放在了堆内存还是栈内存

目标C中的类继承和自定义^块执行

iOS 开发:成员变量(属性,实例变量)的相关知识