mirror of
https://github.com/boostorg/python.git
synced 2026-01-21 17:12:22 +00:00
Handled some reference-counting problems and added some sequence points for exception-safety
[SVN r8227]
This commit is contained in:
384
callback.h
384
callback.h
@@ -16,8 +16,13 @@
|
||||
|
||||
namespace py {
|
||||
|
||||
// Just like the above, except we decrement p's reference count instead of returning it.
|
||||
void expect_and_absorb_non_null(PyObject* p);
|
||||
namespace detail {
|
||||
template <class T>
|
||||
inline void callback_adjust_refcount(PyObject*, Type<T>) {}
|
||||
|
||||
inline void callback_adjust_refcount(PyObject* p, Type<PyObject*>)
|
||||
{ Py_INCREF(p); }
|
||||
}
|
||||
|
||||
// Calling Python from C++
|
||||
template <class R>
|
||||
@@ -25,110 +30,163 @@ struct Callback
|
||||
{
|
||||
static R call_method(PyObject* self, const char* name)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("()"))), Type<R>());
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("()")));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
static R call(PyObject* self)
|
||||
{
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("()")));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(N)"),
|
||||
to_python(a1))), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(NN)"),
|
||||
to_python(a1),
|
||||
to_python(a2))), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(NNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3))), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(NNNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3),
|
||||
to_python(a4))), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(NNNNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3),
|
||||
to_python(a4),
|
||||
to_python(a5))), Type<R>());
|
||||
}
|
||||
|
||||
static R call(PyObject* self)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallFunction(self, const_cast<char*>("()"))), Type<R>());
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static R call(PyObject* self, const A1& a1)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallFunction(self, const_cast<char*>("(N)"),
|
||||
to_python(a1))), Type<R>());
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2)
|
||||
{
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallFunction(self, const_cast<char*>("(NN)"),
|
||||
to_python(a1),
|
||||
to_python(a2))), Type<R>());
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallFunction(self, const_cast<char*>("(NNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3))), Type<R>());
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr p4(to_python(a4));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallFunction(self, const_cast<char*>("(NNNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3),
|
||||
to_python(a4))), Type<R>());
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr p4(to_python(a4));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr p4(to_python(a4));
|
||||
Ptr p5(to_python(a5));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
return from_python(expect_non_null(PyEval_CallFunction(self, const_cast<char*>("(NNNNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3),
|
||||
to_python(a4),
|
||||
to_python(a5))), Type<R>());
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr p4(to_python(a4));
|
||||
Ptr p5(to_python(a5));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get()));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// This specialization wouldn't be needed, but MSVC6 doesn't correctly allow the following:
|
||||
@@ -137,112 +195,142 @@ struct Callback
|
||||
template <>
|
||||
struct Callback<void>
|
||||
{
|
||||
|
||||
static void call_method(PyObject* self, const char* name)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("()")));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("()")));
|
||||
}
|
||||
|
||||
static void call(PyObject* self)
|
||||
{
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("()")));
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(N)"),
|
||||
to_python(a1)));
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(NN)"),
|
||||
to_python(a1),
|
||||
to_python(a2)));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(NNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3)));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(NNNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3),
|
||||
to_python(a4)));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(NNNNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3),
|
||||
to_python(a4),
|
||||
to_python(a5)));
|
||||
}
|
||||
|
||||
static void call(PyObject* self)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallFunction(self, const_cast<char*>("()")));
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static void call(PyObject* self, const A1& a1)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallFunction(self, const_cast<char*>("(N)"),
|
||||
to_python(a1)));
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2)
|
||||
{
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallFunction(self, const_cast<char*>("(NN)"),
|
||||
to_python(a1),
|
||||
to_python(a2)));
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallFunction(self, const_cast<char*>("(NNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3)));
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr p4(to_python(a4));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallFunction(self, const_cast<char*>("(NNNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3),
|
||||
to_python(a4)));
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr p4(to_python(a4));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr p4(to_python(a4));
|
||||
Ptr p5(to_python(a5));
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
expect_and_absorb_non_null(PyEval_CallFunction(self, const_cast<char*>("(NNNNN)"),
|
||||
to_python(a1),
|
||||
to_python(a2),
|
||||
to_python(a3),
|
||||
to_python(a4),
|
||||
to_python(a5)));
|
||||
Ptr p1(to_python(a1));
|
||||
Ptr p2(to_python(a2));
|
||||
Ptr p3(to_python(a3));
|
||||
Ptr p4(to_python(a4));
|
||||
Ptr p5(to_python(a5));
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get()));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace py
|
||||
|
||||
@@ -2,28 +2,6 @@ from gen_function import *
|
||||
import string
|
||||
|
||||
def gen_callback(args):
|
||||
# A template for the call_method function which we're going to generate
|
||||
call_method = '''%{ template <%(class A%n%:, %)>
|
||||
%} static %1 call_method(PyObject* self, const char* name%(, const A%n& a%n%))
|
||||
{
|
||||
%2PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(%(N%))")%(,
|
||||
to_python(a%n)%))%3;
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
call_function = '''%{ template <%(class A%n%:, %)>
|
||||
%} static %1 call(PyObject* self%(, const A%n& a%n%))
|
||||
{
|
||||
%2PyEval_CallFunction(self, const_cast<char*>("(%(N%))")%(,
|
||||
to_python(a%n)%))%3;
|
||||
}
|
||||
|
||||
'''
|
||||
non_void = ('R', 'return from_python(expect_non_null(', '), Type<R>())')
|
||||
void = ('void', 'expect_and_absorb_non_null(', ')')
|
||||
|
||||
return (
|
||||
"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
@@ -43,16 +21,41 @@ def gen_callback(args):
|
||||
|
||||
namespace py {
|
||||
|
||||
// Just like the above, except we decrement p's reference count instead of returning it.
|
||||
void expect_and_absorb_non_null(PyObject* p);
|
||||
namespace detail {
|
||||
template <class T>
|
||||
inline void callback_adjust_refcount(PyObject*, Type<T>) {}
|
||||
|
||||
inline void callback_adjust_refcount(PyObject* p, Type<PyObject*>)
|
||||
{ Py_INCREF(p); }
|
||||
}
|
||||
|
||||
// Calling Python from C++
|
||||
template <class R>
|
||||
struct Callback
|
||||
{
|
||||
""" % args
|
||||
+ gen_functions(call_method, args, 'R', 'return from_python(expect_non_null(', '), Type<R>())')
|
||||
+ gen_functions(call_function, args, 'R', 'return from_python(expect_non_null(', '), Type<R>())')
|
||||
{""" % args
|
||||
|
||||
+ gen_functions('''
|
||||
%{ template <%(class A%n%:, %)>
|
||||
%} static R call_method(PyObject* self, const char* name%(, const A%n& a%n%))
|
||||
{%(
|
||||
Ptr p%n(to_python(a%n));%)
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(%(O%))")%(,
|
||||
p%n.get()%)));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
|
||||
%{ template <%(class A%n%:, %)>
|
||||
%} static R call(PyObject* self%(, const A%n& a%n%))
|
||||
{%(
|
||||
Ptr p%n(to_python(a%n));%)
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(%(O%))")%(,
|
||||
p%n.get()%)));
|
||||
detail::callback_adjust_refcount(result.get(), Type<R>());
|
||||
return from_python(result.get(), Type<R>());
|
||||
}
|
||||
''', args)
|
||||
+
|
||||
"""};
|
||||
|
||||
@@ -63,8 +66,24 @@ template <>
|
||||
struct Callback<void>
|
||||
{
|
||||
"""
|
||||
+ gen_functions(call_method, args, 'void', 'expect_and_absorb_non_null(', ')')
|
||||
+ gen_functions(call_function, args, 'void', 'expect_and_absorb_non_null(', ')')
|
||||
+ gen_functions('''
|
||||
%{ template <%(class A%n%:, %)>
|
||||
%} static void call_method(PyObject* self, const char* name%(, const A%n& a%n%))
|
||||
{%(
|
||||
Ptr p%n(to_python(a%n));%)
|
||||
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(%(O%))")%(,
|
||||
p%n.get()%)));
|
||||
}
|
||||
|
||||
%{ template <%(class A%n%:, %)>
|
||||
%} static void call(PyObject* self%(, const A%n& a%n%))
|
||||
{%(
|
||||
Ptr p%n(to_python(a%n));%)
|
||||
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(%(O%))")%(,
|
||||
p%n.get()%)));
|
||||
}
|
||||
''', args)
|
||||
+
|
||||
"""};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user