fixes for directors + pointers
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@7860 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
af0aab45d7
commit
f3c24eff33
16 changed files with 808 additions and 137 deletions
|
|
@ -10,15 +10,30 @@
|
|||
#ifdef __cplusplus
|
||||
|
||||
namespace Swig {
|
||||
|
||||
GCItem::~GCItem()
|
||||
{
|
||||
}
|
||||
|
||||
/* simple thread abstraction for pthreads on win32 */
|
||||
Director::~Director() {
|
||||
swig_decref();
|
||||
}
|
||||
|
||||
/* wrap a python object, optionally taking ownership */
|
||||
Director::Director(PyObject* self) : swig_self(self), swig_disown_flag(false) {
|
||||
#ifdef __PTHREAD__
|
||||
MUTEX_INIT(swig_mutex_own);
|
||||
#endif
|
||||
swig_incref();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Director::swig_up = false;
|
||||
|
||||
#ifdef __PTHREAD__
|
||||
MUTEX_INIT(Director::swig_mutex_up);
|
||||
pthread_mutex_t SWIG_MUTEX_INIT(Director::swig_mutex_up);
|
||||
pthread_t Director::swig_mutex_thread;
|
||||
bool Director::swig_mutex_active = false;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,6 +14,22 @@
|
|||
#include <string>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
/*
|
||||
Use -DSWIG_DIRECTOR_NOVTABLE if you don't want to generate a 'virtual
|
||||
table', and avoid multiple GetAttr calls to retreive the python
|
||||
methods.
|
||||
*/
|
||||
|
||||
#ifndef SWIG_DIRECTOR_NOVTABLE
|
||||
#ifndef SWIG_DIRECTOR_VTABLE
|
||||
#define SWIG_DIRECTOR_VTABLE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -50,6 +66,7 @@
|
|||
# ifndef SWIG_DIRECTOR_RTDIR
|
||||
# define SWIG_DIRECTOR_RTDIR
|
||||
#include <map>
|
||||
|
||||
namespace Swig {
|
||||
class Director;
|
||||
SWIGINTERN std::map<void*,Director*>& get_rtdir_map() {
|
||||
|
|
@ -85,6 +102,117 @@ extern "C" {
|
|||
|
||||
namespace Swig {
|
||||
|
||||
/* memory handler */
|
||||
struct GCItem
|
||||
{
|
||||
virtual ~GCItem() = 0;
|
||||
|
||||
virtual int get_own() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct GCItem_var
|
||||
{
|
||||
GCItem_var(GCItem *item = 0) : _item(item)
|
||||
{
|
||||
}
|
||||
|
||||
GCItem_var& operator=(GCItem *item)
|
||||
{
|
||||
GCItem *tmp = _item;
|
||||
_item = item;
|
||||
delete tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~GCItem_var()
|
||||
{
|
||||
delete _item;
|
||||
}
|
||||
|
||||
GCItem * operator->() const
|
||||
{
|
||||
return _item;
|
||||
}
|
||||
|
||||
private:
|
||||
GCItem *_item;
|
||||
};
|
||||
|
||||
struct GCItem_Object : GCItem
|
||||
{
|
||||
GCItem_Object(int own) : _own(own)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~GCItem_Object()
|
||||
{
|
||||
}
|
||||
|
||||
int get_own()
|
||||
{
|
||||
return _own;
|
||||
}
|
||||
|
||||
private:
|
||||
int _own;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct GCItem_T : GCItem
|
||||
{
|
||||
GCItem_T(Type *ptr) : _ptr(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~GCItem_T()
|
||||
{
|
||||
delete _ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
Type *_ptr;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct GCArray_T : GCItem
|
||||
{
|
||||
GCArray_T(Type *ptr) : _ptr(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~GCArray_T()
|
||||
{
|
||||
delete[] _ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
Type *_ptr;
|
||||
};
|
||||
|
||||
|
||||
/* unknown exception handler */
|
||||
class UnknownExceptionHandler
|
||||
{
|
||||
static void handler();
|
||||
public:
|
||||
|
||||
#ifdef SWIG_DIRECTOR_UEH
|
||||
std::unexpected_handler old;
|
||||
UnknownExceptionHandler(std::unexpected_handler nh = handler)
|
||||
{
|
||||
old = std::set_unexpected(nh);
|
||||
}
|
||||
|
||||
~UnknownExceptionHandler()
|
||||
{
|
||||
std::set_unexpected(old);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/* base class for director exceptions */
|
||||
class DirectorException {
|
||||
protected:
|
||||
|
|
@ -120,25 +248,6 @@ namespace Swig {
|
|||
}
|
||||
};
|
||||
|
||||
/* unknown exception handler */
|
||||
class UnknownExceptionHandler
|
||||
{
|
||||
static void handler();
|
||||
public:
|
||||
|
||||
#ifdef SWIG_DIRECTOR_UEH
|
||||
std::unexpected_handler old;
|
||||
UnknownExceptionHandler(std::unexpected_handler nh = handler)
|
||||
{
|
||||
old = std::set_unexpected(nh);
|
||||
}
|
||||
|
||||
~UnknownExceptionHandler()
|
||||
{
|
||||
std::set_unexpected(old);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/* type mismatch in the return value from a python method call */
|
||||
class DirectorTypeMismatchException : public Swig::DirectorException {
|
||||
|
|
@ -194,20 +303,41 @@ namespace Swig {
|
|||
};
|
||||
|
||||
|
||||
/* simple thread abstraction for pthreads on win32 */
|
||||
/* simple thread abstraction for pthreads on win32 */
|
||||
#ifdef __THREAD__
|
||||
#define __PTHREAD__
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
#define pthread_mutex_lock EnterCriticalSection
|
||||
#define pthread_mutex_unlock LeaveCriticalSection
|
||||
#define pthread_mutex_t CRITICAL_SECTION
|
||||
#define MUTEX_INIT(var) CRITICAL_SECTION var
|
||||
# define __PTHREAD__
|
||||
# if defined(_WIN32) || defined(__WIN32__)
|
||||
# define pthread_mutex_lock EnterCriticalSection
|
||||
# define pthread_mutex_unlock LeaveCriticalSection
|
||||
# define pthread_mutex_t CRITICAL_SECTION
|
||||
# define SWIG_MUTEX_INIT(var) var
|
||||
# endif
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
# include <pthread.h>
|
||||
# define SWIG_MUTEX_INIT(var) var = PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
|
||||
#ifdef __PTHREAD__
|
||||
# define SWIG_GUARD(mutex) Guard _guard(mutex)
|
||||
#else
|
||||
# define SWIG_GUARD(mutex)
|
||||
#endif
|
||||
|
||||
|
||||
struct Guard
|
||||
{
|
||||
pthread_mutex_t *_mutex;
|
||||
|
||||
Guard(pthread_mutex_t &mutex) : _mutex(&mutex)
|
||||
{
|
||||
pthread_mutex_lock(_mutex);
|
||||
}
|
||||
|
||||
~Guard()
|
||||
{
|
||||
pthread_mutex_unlock(_mutex);
|
||||
}
|
||||
};
|
||||
|
||||
/* director base class */
|
||||
class Director {
|
||||
|
|
@ -248,9 +378,7 @@ namespace Swig {
|
|||
|
||||
public:
|
||||
/* wrap a python object, optionally taking ownership */
|
||||
Director(PyObject* self) : swig_self(self), swig_disown_flag(false) {
|
||||
swig_incref();
|
||||
}
|
||||
Director(PyObject* self);
|
||||
|
||||
/* discard our reference at destruction */
|
||||
virtual ~Director();
|
||||
|
|
@ -321,6 +449,53 @@ namespace Swig {
|
|||
|
||||
virtual void swig_set_inner(const char* /* name */, bool /* val */) const {
|
||||
}
|
||||
|
||||
/* ownership managing */
|
||||
private:
|
||||
typedef std::map<void*, GCItem_var> ownership_map;
|
||||
mutable ownership_map owner;
|
||||
mutable pthread_mutex_t swig_mutex_own;
|
||||
|
||||
public:
|
||||
template <typename Type>
|
||||
void swig_acquire_ownership_array(Type *vptr) const
|
||||
{
|
||||
if (vptr) {
|
||||
SWIG_GUARD(swig_mutex_own);
|
||||
owner[vptr] = new GCArray_T<Type>(vptr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void swig_acquire_ownership(Type *vptr) const
|
||||
{
|
||||
if (vptr) {
|
||||
SWIG_GUARD(swig_mutex_own);
|
||||
owner[vptr] = new GCItem_T<Type>(vptr);
|
||||
}
|
||||
}
|
||||
|
||||
void swig_acquire_ownership_obj(void *vptr, int own) const
|
||||
{
|
||||
if (vptr && own) {
|
||||
SWIG_GUARD(swig_mutex_own);
|
||||
owner[vptr] = new GCItem_Object(own);
|
||||
}
|
||||
}
|
||||
|
||||
int swig_release_ownership(void *vptr) const
|
||||
{
|
||||
int own = 0;
|
||||
if (vptr) {
|
||||
SWIG_GUARD(swig_mutex_own);
|
||||
ownership_map::iterator iter = owner.find(vptr);
|
||||
if (iter != owner.end()) {
|
||||
own = iter->second->get_own();
|
||||
owner.erase(iter);
|
||||
}
|
||||
}
|
||||
return own;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,13 @@ namespace swig {
|
|||
|
||||
Hence, this class is purely internal and not visible at the wrapped side.
|
||||
*/
|
||||
namespace swig {
|
||||
%ignore PyObject_var;
|
||||
struct PyObject_var {};
|
||||
%apply PyObject * {PyObject_var};
|
||||
%apply PyObject * const& {PyObject_var const&};
|
||||
}
|
||||
|
||||
%{
|
||||
namespace swig {
|
||||
struct PyObject_var : PyObject_ptr {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace swig {
|
|||
|
||||
template <>
|
||||
struct traits_check<PyObject_ptr, value_category> {
|
||||
static bool check(PyObject *) {
|
||||
static bool check(PyObject_ptr) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
@ -60,6 +60,41 @@ namespace swig {
|
|||
}
|
||||
|
||||
|
||||
%fragment(SWIG_Traits_frag(swig::PyObject_var),"header",fragment="StdTraits") {
|
||||
namespace swig {
|
||||
template <> struct traits<PyObject_var > {
|
||||
typedef value_category category;
|
||||
static const char* type_name() { return "PyObject_var"; }
|
||||
};
|
||||
|
||||
template <> struct traits_from<PyObject_var> {
|
||||
typedef PyObject_var value_type;
|
||||
static PyObject *from(const value_type& val) {
|
||||
PyObject *obj = static_cast<PyObject *>(val);
|
||||
Py_XINCREF(obj);
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traits_check<PyObject_var, value_category> {
|
||||
static bool check(PyObject_var) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct traits_asval<PyObject_var > {
|
||||
typedef PyObject_var value_type;
|
||||
static int asval(PyObject *obj, value_type *val) {
|
||||
if (val) *val = obj;
|
||||
return SWIG_OK;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
%fragment("PySequence_Base","header")
|
||||
{
|
||||
|
||||
|
|
@ -79,6 +114,15 @@ namespace std {
|
|||
operator()(const swig::PyObject_ptr& v, const swig::PyObject_ptr& w) const
|
||||
{ return PyObject_Compare(v, w) < 0; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct less <swig::PyObject_var>: public binary_function<swig::PyObject_var, swig::PyObject_var, bool>
|
||||
{
|
||||
bool
|
||||
operator()(const swig::PyObject_var& v, const swig::PyObject_var& w) const
|
||||
{ return PyObject_Compare(v, w) < 0; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace swig {
|
||||
|
|
@ -706,7 +750,7 @@ namespace swig
|
|||
|
||||
%fragment("PySequence_Cont");
|
||||
|
||||
%newobject iterator(PyObject *PYTHON_SELF);
|
||||
%newobject iterator(PyObject **PYTHON_SELF);
|
||||
%extend {
|
||||
swig::PySequence_OutputIterator* iterator(PyObject **PYTHON_SELF) {
|
||||
return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
|
||||
|
|
|
|||
|
|
@ -11,16 +11,19 @@
|
|||
/* Common SWIG API */
|
||||
|
||||
/* for raw pointers */
|
||||
#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags)
|
||||
#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
|
||||
#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
|
||||
#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags)
|
||||
#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src)
|
||||
#define swig_owntype int
|
||||
|
||||
/* for raw packed data */
|
||||
#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
|
||||
#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
|
||||
|
||||
/* for class or struct pointers */
|
||||
#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags)
|
||||
#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags)
|
||||
#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
|
||||
#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
|
||||
|
||||
/* for C or C++ function pointers */
|
||||
#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
|
||||
|
|
@ -282,7 +285,7 @@ SWIGINTERN PyObject*
|
|||
PySwigObject_acquire(PyObject *v)
|
||||
{
|
||||
PySwigObject *sobj = (PySwigObject *)v;
|
||||
sobj->own = 1;
|
||||
sobj->own = SWIG_POINTER_OWN;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
|
@ -642,7 +645,7 @@ SWIG_This()
|
|||
SWIGRUNTIMEINLINE PySwigObject *
|
||||
SWIG_Python_GetSwigThis(PyObject *pyobj)
|
||||
{
|
||||
if (PySwigObject_Check(pyobj)) {
|
||||
if (pyobj && PySwigObject_Check(pyobj)) {
|
||||
return (PySwigObject *) pyobj;
|
||||
} else {
|
||||
PyObject *obj = 0;
|
||||
|
|
@ -663,17 +666,37 @@ SWIG_Python_GetSwigThis(PyObject *pyobj)
|
|||
obj = PyObject_GetAttr(pyobj,SWIG_This());
|
||||
Py_XDECREF(obj);
|
||||
#endif
|
||||
if (PyErr_Occurred()) {
|
||||
obj = 0;
|
||||
if (!obj || PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
return 0;
|
||||
}
|
||||
if (PySwigObject_Check(obj)) {
|
||||
return (PySwigObject *)obj;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Acquire a pointer value */
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_AcquirePtr(PyObject *obj, int own) {
|
||||
if (own) {
|
||||
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
|
||||
if (sobj) {
|
||||
int oldown = sobj->own;
|
||||
sobj->own = own;
|
||||
return oldown;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return obj && PySwigObject_Check(obj) ? (PySwigObject *) obj : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert a pointer value */
|
||||
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) {
|
||||
SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
|
||||
if (!obj) return SWIG_ERROR;
|
||||
if (obj == Py_None) {
|
||||
*ptr = 0;
|
||||
|
|
@ -703,6 +726,7 @@ SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags)
|
|||
}
|
||||
}
|
||||
if (sobj) {
|
||||
if (own) *own = sobj->own;
|
||||
if (flags & SWIG_POINTER_DISOWN) {
|
||||
sobj->own = 0;
|
||||
}
|
||||
|
|
@ -717,7 +741,7 @@ SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags)
|
|||
SWIGRUNTIME int
|
||||
SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
|
||||
if (!PyCFunction_Check(obj)) {
|
||||
return SWIG_Python_ConvertPtr(obj, ptr, ty, 0);
|
||||
return SWIG_ConvertPtr(obj, ptr, ty, 0);
|
||||
} else {
|
||||
const char *desc = 0;
|
||||
void *vptr = 0;
|
||||
|
|
@ -814,7 +838,8 @@ SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
|
|||
}
|
||||
return NULL;
|
||||
} else {
|
||||
PyObject *robj = PySwigObject_New((void *) ptr, type, (flags & SWIG_POINTER_OWN));
|
||||
int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
|
||||
PyObject *robj = PySwigObject_New((void *) ptr, type, own);
|
||||
PySwigClientData *clientdata = (PySwigClientData *)type->clientdata;
|
||||
if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
|
||||
PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
|
||||
|
|
@ -914,8 +939,7 @@ SWIG_Python_DestroyModule(void *vptr)
|
|||
ty->clientdata = 0;
|
||||
}
|
||||
}
|
||||
Py_DECREF(SWIG_This());
|
||||
/* and, what else ... */
|
||||
Py_DECREF(SWIG_This());
|
||||
}
|
||||
|
||||
SWIGRUNTIME void
|
||||
|
|
|
|||
|
|
@ -39,11 +39,11 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
|
|||
*alloc = SWIG_NEWOBJ;
|
||||
}
|
||||
else {
|
||||
*cptr = cstr;
|
||||
*cptr = PyString_AsString(obj);
|
||||
*alloc = SWIG_OLDOBJ;
|
||||
}
|
||||
} else {
|
||||
*cptr = cstr;
|
||||
*cptr = PyString_AsString(obj);
|
||||
}
|
||||
}
|
||||
if (psize) *psize = len + 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue