【问题标题】:Problem wrapping a C++ class with a mutex in a member, using Swig使用 Swig 在成员中使用互斥体包装 C++ 类时出现问题
【发布时间】:2019-11-24 23:54:14
【问题描述】:

我有一个包含 (Poco) 互斥锁的 C++ 类:

class ClassWithMutex
{
    public:
                                ClassWithMutex();
        virtual                 ~ClassWithMutex();

        Poco::Mutex             mMyMutex;

    private:
        ClassWithMutex(const ClassWithMutex& );
        ClassWithMutex& operator=(const ClassWithMutex& other);

};

还有另一个类,使用它:

class ClassHavingAClassWithMutex
{
    public:
        ClassHavingAClassWithMutex();
        ~ClassHavingAClassWithMutex();
        ClassWithMutex      A;

    private:
        ClassHavingAClassWithMutex(const ClassHavingAClassWithMutex&);
        ClassHavingAClassWithMutex& ClassHavingAClassWithMutex::operator=(const ClassHavingAClassWithMutex& other);

};

尝试为 ClassHavingAClassWithMutex 创建包装器时,出现错误:

Error   C2248   'ClassWithMutex::operator =': cannot access private member declared in class 'ClassWithMutex'   mvr C:\builds\vs2015\mvr\python_package\src\mvr\mvrPYTHON_wrap.cxx  6493    

Swig 生成的代码如下所示:

SWIGINTERN PyObject *_wrap_ClassWithMutex_mMyMutex_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  ClassWithMutex *arg1 = (ClassWithMutex *) 0 ;
  void *argp1 = 0 ;
  int res1 = 0 ;
  PyObject *swig_obj[1] ;
  Poco::Mutex result;

  if (!args) SWIG_fail;
  swig_obj[0] = args;
  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ClassWithMutex, 0 |  0 );
  if (!SWIG_IsOK(res1)) {
    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ClassWithMutex_mMyMutex_get" "', argument " "1"" of type '" "ClassWithMutex *""'"); 
  }
  arg1 = reinterpret_cast< ClassWithMutex * >(argp1);
  {
    SWIG_PYTHON_THREAD_BEGIN_ALLOW;
    result =  ((arg1)->mMyMutex);
    SWIG_PYTHON_THREAD_END_ALLOW;
  }
  resultobj = SWIG_NewPointerObj((new Poco::Mutex(static_cast< const Poco::Mutex& >(result))), SWIGTYPE_p_Poco__Mutex, SWIG_POINTER_OWN |  0 );
  return resultobj;
fail:
  return NULL;
}

以及从这一行发出的错误:

if (arg1) (arg1)->A = *arg2;
and
resultobj = SWIG_NewPointerObj((new Poco::Mutex(static_cast< const Poco::Mutex& >(result))), SWIGTYPE_p_Poco__Mutex, SWIG_POINTER_OWN |  0 );

Swig 接口文件:

%immutable
%include "aiClassWithMutex.h"
%include "ClassHavingAClassWithMutex.h"
%mutable

关于如何用 Swig 正确包装上述类有什么建议吗?我在上面的课程中将复制和分配ctor的私有化,以防止任何复制,但似乎swig坚持这样做?

【问题讨论】:

  • 为什么要有私有的拷贝构造函数?如果您想禁用复制,请考虑“三法则”,或者对于更新的 C++,请考虑“五法则”。
  • @UlrichEckhardt 用于防止复制的私有复制构造函数,因为互斥体。
  • 有点多余,因为 mutex 成员使类既不可复制又不可分配。分配是一些代码尝试的。

标签: python c++ swig


【解决方案1】:

这不是由复制构造函数引起的,而是由属性设置器引起的(b/c A 是公共的)。正如 cmets 中所讨论的,一种选择是通过添加以下内容来隐藏它:

%ignore ClassWithMutex::mMyMutex;

在 .i 文件中的 %include "aiClassWithMutex.h" 之前。

如前所述,SWIG 在使 mMyMutex 不可变时诉诸复制。 AFAICT,除了编写类型图和滥用optimal 设置(首先防止构建临时文件)之外,别无他法。这样,一个功能性的 .i 文件看起来像:

%module mut

%{  
#include "aiClassWithMutex.h"
#include "ClassHavingAClassWithMutex.h"
%}      

%feature("immutable", 1) ClassWithMutex::mMyMutex;
%typemap(out, optimal="1") Poco::Mutex %{
  $result = SWIG_NewPointerObj(($1_ltype*)&$1, $&1_descriptor, 0);
%}      
%include "aiClassWithMutex.h"
%include "ClassHavingAClassWithMutex.h"

【讨论】:

  • 在帖子中添加了 .i 代码,但这并没有解决问题..?
  • 为我工作......你有哪个版本的 SWIG? (我问的是 b/c,我只是注意到 SWIG4 readonly 现在是 immutable 并且它似乎根本不生成 A_set,因为它不会编译。)
  • 我正在使用 Swig 4。我确实尝试了不可变/可变,现在我在“getter”中得到了错误。我更新了帖子。
  • 我看到 .. 因为它是从 getter 按值复制的。你想访问互斥锁吗? IE。变量应该完全隐藏还是通过代理中的指针访问?其实,让我把这两个都挖出来解决一下。
  • 使用指针数据成员,SWIG 没有复制,因此不会出现上述问题。 (事实上​​,这是 typemap 解决方法所依赖的。)所以,是的,AFAICT,在你的情况下应该没有任何问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-19
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多