简体   繁体   中英

Problem wrapping a C++ class with a mutex in a member, using Swig

I have a C++ class containing a (Poco) mutex:

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

        Poco::Mutex             mMyMutex;

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

};

And another class, using it:

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

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

};

When trying to create a wrapper for ClassHavingAClassWithMutex, I get an error:

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    

where the Swig generated code looks like this:

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;
}

and errors emitted from this line:

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 interface file:

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

Any suggestions on how to properly wrap the classes above with Swig? I made the copy and assignment ctor's private in the classes above, in order to prevent any copying, but it seems swig insist on it?

That's not caused by the copy constructor but the property setter (b/c A is public). As discussed in the comments, one option is to hide it, by adding:

%ignore ClassWithMutex::mMyMutex;

before the %include "aiClassWithMutex.h" in the .i file.

Also as discussed, SWIG resorts to copying when making mMyMutex immutable. AFAICT, there's no way around that other than writing a typemap and misusing the optimal setting (to prevent the construction of a temporary in the first place). With that, a functional .i file looks like:

%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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM