Index: boost/python/signature.hpp =================================================================== --- boost/python/signature.hpp (revision 58712) +++ boost/python/signature.hpp (working copy) @@ -52,16 +52,23 @@ // // template // inline mpl::vector -// get_signature(RT(*)(T0...TN), void* = 0) +// get_signature(RT(BOOST_PYTHON_FN_CC *)(T0...TN), void* = 0) // { // return mpl::list(); // } // +// where BOOST_PYTHON_FN_CC is a calling convention keyword, can be +// +// empty, for default calling convention +// __cdecl (if BOOST_PYTHON_ENABLE_CDECL is defined) +// __stdcall (if BOOST_PYTHON_ENABLE_STDCALL is defined) +// __fastcall (if BOOST_PYTHON_ENABLE_FASTCALL is defined) +// // And, for an appropriate assortment of cv-qualifications:: // // template // inline mpl::vector -// get_signature(RT(ClassT::*)(T0...TN) cv)) +// get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv)) // { // return mpl::list(); // } @@ -72,7 +79,7 @@ // , typename most_derived::type& // , T0...TN // > -// get_signature(RT(ClassT::*)(T0...TN) cv), Target*) +// get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv), Target*) // { // return mpl::list(); // } @@ -87,7 +94,8 @@ // // These functions extract the return type, class (for member // functions) and arguments of the input signature and stuff them in -// an mpl type sequence. Note that cv-qualification is dropped from +// an mpl type sequence (the calling convention is dropped). +// Note that cv-qualification is dropped from // the "hidden this" argument of member functions; that is a // necessary sacrifice to ensure that an lvalue from_python converter // is used. A pointer is not used so that None will be rejected for @@ -100,10 +108,64 @@ // // @group { +// 'default' calling convention + +# define BOOST_PYTHON_FN_CC + # define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FN_CC + +// __cdecl calling convention + +# if defined(BOOST_PYTHON_ENABLE_CDECL) + +# define BOOST_PYTHON_FN_CC __cdecl +# define BOOST_PYTHON_FN_CC_IS_CDECL + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) + +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FN_CC +# undef BOOST_PYTHON_FN_CC_IS_CDECL + +# endif // defined(BOOST_PYTHON_ENABLE_CDECL) + +// __stdcall calling convention + +# if defined(BOOST_PYTHON_ENABLE_STDCALL) + +# define BOOST_PYTHON_FN_CC __stdcall + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) + +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FN_CC + +# endif // defined(BOOST_PYTHON_ENABLE_STDCALL) + +// __fastcall calling convention + +# if defined(BOOST_PYTHON_ENABLE_FASTCALL) + +# define BOOST_PYTHON_FN_CC __fastcall + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) + +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FN_CC + +# endif // defined(BOOST_PYTHON_ENABLE_FASTCALL) + # undef BOOST_PYTHON_LIST_INC // } @@ -120,17 +182,24 @@ # define N BOOST_PP_ITERATION() + // as 'get_signature(RT(*)(T0...TN), void* = 0)' is the same + // function as 'get_signature(RT(__cdecl *)(T0...TN), void* = 0)', + // we don't define it twice +# if !defined(BOOST_PYTHON_FN_CC_IS_CDECL) + template < class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> inline BOOST_PYTHON_LIST_INC(N)< RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> -get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0) +get_signature(RT(BOOST_PYTHON_FN_CC *)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0) { return BOOST_PYTHON_LIST_INC(N)< RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) >(); } +# endif // !defined(BOOST_PYTHON_FN_CC_IS_CDECL) + # undef N # define BOOST_PP_ITERATION_PARAMS_2 \ @@ -146,7 +215,7 @@ class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> -get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) +get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) { return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) @@ -165,7 +234,7 @@ BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) > get_signature( - RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q + RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q , Target* ) { Index: libs/python/test/calling_conventions.cpp =================================================================== --- libs/python/test/calling_conventions.cpp (revision 0) +++ libs/python/test/calling_conventions.cpp (revision 0) @@ -0,0 +1,158 @@ +// +// adapted from bind_stdcall_test.cpp - test for bind.hpp + __stdcall (free functions) +// The purpose of this simple test is to determine if a function can be +// called from Python with the various existing calling conventions +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#if !defined(TEST_INCLUDE_RECURSION) + +#define TEST_INCLUDE_RECURSION + +//------------------------------------------------------------------------------ +// this section is the main body of the test extension module + +#define BOOST_PYTHON_ENABLE_CDECL +#define BOOST_PYTHON_ENABLE_STDCALL +#define BOOST_PYTHON_ENABLE_FASTCALL +#include +#include +#include +using namespace boost::python; + +// first define test functions for every calling convention + +#define TEST_DECLARE_FUNCTIONS + +#define TESTED_CALLING_CONVENTION __cdecl +#include "calling_conventions.cpp" +#undef TESTED_CALLING_CONVENTION + +#define TESTED_CALLING_CONVENTION __stdcall +#include "calling_conventions.cpp" +#undef TESTED_CALLING_CONVENTION + +#define TESTED_CALLING_CONVENTION __fastcall +#include "calling_conventions.cpp" +#undef TESTED_CALLING_CONVENTION + +#undef TEST_DECLARE_FUNCTIONS + +// then create a module wrapping the defined functions for every calling convention + +BOOST_PYTHON_MODULE( calling_conventions_ext ) +{ + +#define TEST_WRAP_FUNCTIONS + +#define TESTED_CALLING_CONVENTION __cdecl +#include "calling_conventions.cpp" +#undef TESTED_CALLING_CONVENTION + +#define TESTED_CALLING_CONVENTION __stdcall +#include "calling_conventions.cpp" +#undef TESTED_CALLING_CONVENTION + +#define TESTED_CALLING_CONVENTION __fastcall +#include "calling_conventions.cpp" +#undef TESTED_CALLING_CONVENTION + +#undef TEST_WRAP_FUNCTIONS + +} + +#else // !defined(TEST_INCLUDE_RECURSION) + +//------------------------------------------------------------------------------ +// this section defines the functions to be wrapped + +# if defined(TEST_DECLARE_FUNCTIONS) + +# if !defined(TESTED_CALLING_CONVENTION) +# error "One calling convention must be defined" +# endif // !defined(TESTED_CALLING_CONVENTION) + +namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) { + + long TESTED_CALLING_CONVENTION f_0() + { + return 17041L; + } + + long TESTED_CALLING_CONVENTION f_1(long a) + { + return a; + } + + long TESTED_CALLING_CONVENTION f_2(long a, long b) + { + return a + 10 * b; + } + + long TESTED_CALLING_CONVENTION f_3(long a, long b, long c) + { + return a + 10 * b + 100 * c; + } + + long TESTED_CALLING_CONVENTION f_4(long a, long b, long c, long d) + { + return a + 10 * b + 100 * c + 1000 * d; + } + + long TESTED_CALLING_CONVENTION f_5(long a, long b, long c, long d, long e) + { + return a + 10 * b + 100 * c + 1000 * d + 10000 * e; + } + + long TESTED_CALLING_CONVENTION f_6(long a, long b, long c, long d, long e, long f) + { + return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f; + } + + long TESTED_CALLING_CONVENTION f_7(long a, long b, long c, long d, long e, long f, long g) + { + return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g; + } + + long TESTED_CALLING_CONVENTION f_8(long a, long b, long c, long d, long e, long f, long g, long h) + { + return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h; + } + + long TESTED_CALLING_CONVENTION f_9(long a, long b, long c, long d, long e, long f, long g, long h, long i) + { + return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i; + } + +} // namespace test##TESTED_CALLING_CONVENTION + +# endif // defined(TEST_DECLARE_FUNCTIONS) + +//------------------------------------------------------------------------------ +// this section wraps the functions + +# if defined(TEST_WRAP_FUNCTIONS) + +# if !defined(TESTED_CALLING_CONVENTION) +# error "One calling convention must be defined" +# endif // !defined(TESTED_CALLING_CONVENTION) + + def("f_0" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_0); + def("f_1" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_1); + def("f_2" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_2); + def("f_3" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_3); + def("f_4" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_4); + def("f_5" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_5); + def("f_6" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_6); + def("f_7" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_7); + def("f_8" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_8); + def("f_9" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_9); + +# endif // defined(TEST_WRAP_FUNCTIONS) + +#endif // !defined(TEST_INCLUDE_RECURSION) Index: libs/python/test/calling_conventions_mf.cpp =================================================================== --- libs/python/test/calling_conventions_mf.cpp (revision 0) +++ libs/python/test/calling_conventions_mf.cpp (revision 0) @@ -0,0 +1,159 @@ +// +// adapted from bind_stdcall_mf_test.cpp - test for bind.hpp + __stdcall (free functions) +// The purpose of this simple test is to determine if a function can be +// called from Python with the various existing calling conventions +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#if !defined(TEST_INCLUDE_RECURSION) + +#define TEST_INCLUDE_RECURSION + +//------------------------------------------------------------------------------ +// this section is the main body of the test extension module + +#define BOOST_PYTHON_ENABLE_CDECL +#define BOOST_PYTHON_ENABLE_STDCALL +#define BOOST_PYTHON_ENABLE_FASTCALL +#include +#include +#include +using namespace boost::python; + +// first define test functions for every calling convention + +#define TEST_DECLARE_FUNCTIONS + +#define TESTED_CALLING_CONVENTION __cdecl +#include "calling_conventions_mf.cpp" +#undef TESTED_CALLING_CONVENTION + +#define TESTED_CALLING_CONVENTION __stdcall +#include "calling_conventions_mf.cpp" +#undef TESTED_CALLING_CONVENTION + +#define TESTED_CALLING_CONVENTION __fastcall +#include "calling_conventions_mf.cpp" +#undef TESTED_CALLING_CONVENTION + +#undef TEST_DECLARE_FUNCTIONS + +// then create a module wrapping the defined functions for every calling convention + +BOOST_PYTHON_MODULE( calling_conventions_mf_ext ) +{ + +#define TEST_WRAP_FUNCTIONS + +#define TESTED_CALLING_CONVENTION __cdecl +#include "calling_conventions_mf.cpp" +#undef TESTED_CALLING_CONVENTION + +#define TESTED_CALLING_CONVENTION __stdcall +#include "calling_conventions_mf.cpp" +#undef TESTED_CALLING_CONVENTION + +#define TESTED_CALLING_CONVENTION __fastcall +#include "calling_conventions_mf.cpp" +#undef TESTED_CALLING_CONVENTION + +#undef TEST_WRAP_FUNCTIONS + +} + +#else // !defined(TEST_INCLUDE_RECURSION) + +//------------------------------------------------------------------------------ +// this section defines the functions to be wrapped + +# if defined(TEST_DECLARE_FUNCTIONS) + +# if !defined(TESTED_CALLING_CONVENTION) +# error "One calling convention must be defined" +# endif // !defined(TESTED_CALLING_CONVENTION) + +namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) { + +struct X +{ + mutable unsigned int hash; + + X(): hash(0) {} + + void TESTED_CALLING_CONVENTION f0() { f1(17); } + void TESTED_CALLING_CONVENTION g0() const { g1(17); } + + void TESTED_CALLING_CONVENTION f1(int a1) { hash = (hash * 17041 + a1) % 32768; } + void TESTED_CALLING_CONVENTION g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; } + + void TESTED_CALLING_CONVENTION f2(int a1, int a2) { f1(a1); f1(a2); } + void TESTED_CALLING_CONVENTION g2(int a1, int a2) const { g1(a1); g1(a2); } + + void TESTED_CALLING_CONVENTION f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); } + void TESTED_CALLING_CONVENTION g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); } + + void TESTED_CALLING_CONVENTION f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); } + void TESTED_CALLING_CONVENTION g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); } + + void TESTED_CALLING_CONVENTION f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); } + void TESTED_CALLING_CONVENTION g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); } + + void TESTED_CALLING_CONVENTION f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); } + void TESTED_CALLING_CONVENTION g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); } + + void TESTED_CALLING_CONVENTION f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); } + void TESTED_CALLING_CONVENTION g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); } + + void TESTED_CALLING_CONVENTION f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); } + void TESTED_CALLING_CONVENTION g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); } +}; + +} // namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) + +# endif // defined(TEST_DECLARE_FUNCTIONS) + +//------------------------------------------------------------------------------ +// this section wraps the functions + +# if defined(TEST_WRAP_FUNCTIONS) + +# if !defined(TESTED_CALLING_CONVENTION) +# error "One calling convention must be defined" +# endif // !defined(TESTED_CALLING_CONVENTION) + +{ + + typedef BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::X X; + + class_("X" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION)) + .def("f0", &X::f0) + .def("g0", &X::g0) + .def("f1", &X::f1) + .def("g1", &X::g1) + .def("f2", &X::f2) + .def("g2", &X::g2) + .def("f3", &X::f3) + .def("g3", &X::g3) + .def("f4", &X::f4) + .def("g4", &X::g4) + .def("f5", &X::f5) + .def("g5", &X::g5) + .def("f6", &X::f6) + .def("g6", &X::g6) + .def("f7", &X::f7) + .def("g7", &X::g7) + .def("f8", &X::f8) + .def("g8", &X::g8) + .def_readonly("hash", &X::hash) + ; + +} + +# endif // defined(TEST_WRAP_FUNCTIONS) + +#endif // !defined(TEST_INCLUDE_RECURSION) Index: libs/python/test/calling_conventions_mf.py =================================================================== --- libs/python/test/calling_conventions_mf.py (revision 0) +++ libs/python/test/calling_conventions_mf.py (revision 0) @@ -0,0 +1,84 @@ +# Copyright Nicolas Lelong, 2010. Distributed under the Boost +# Software License, Version 1.0 (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +""" +>>> from calling_conventions_mf_ext import * +>>> x = X__cdecl() +>>> x.f0() +>>> x.g0() +>>> x.f1(1) +>>> x.g1(1) +>>> x.f2(1, 2) +>>> x.g2(1, 2) +>>> x.f3(1, 2, 3) +>>> x.g3(1, 2, 3) +>>> x.f4(1, 2, 3, 4) +>>> x.g4(1, 2, 3, 4) +>>> x.f5(1, 2, 3, 4, 5) +>>> x.g5(1, 2, 3, 4, 5) +>>> x.f6(1, 2, 3, 4, 5, 6) +>>> x.g6(1, 2, 3, 4, 5, 6) +>>> x.f7(1, 2, 3, 4, 5, 6, 7) +>>> x.g7(1, 2, 3, 4, 5, 6, 7) +>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8) +>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8) +>>> x.hash +2155 +>>> x = X__stdcall() +>>> x.f0() +>>> x.g0() +>>> x.f1(1) +>>> x.g1(1) +>>> x.f2(1, 2) +>>> x.g2(1, 2) +>>> x.f3(1, 2, 3) +>>> x.g3(1, 2, 3) +>>> x.f4(1, 2, 3, 4) +>>> x.g4(1, 2, 3, 4) +>>> x.f5(1, 2, 3, 4, 5) +>>> x.g5(1, 2, 3, 4, 5) +>>> x.f6(1, 2, 3, 4, 5, 6) +>>> x.g6(1, 2, 3, 4, 5, 6) +>>> x.f7(1, 2, 3, 4, 5, 6, 7) +>>> x.g7(1, 2, 3, 4, 5, 6, 7) +>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8) +>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8) +>>> x.hash +2155 +>>> x = X__fastcall() +>>> x.f0() +>>> x.g0() +>>> x.f1(1) +>>> x.g1(1) +>>> x.f2(1, 2) +>>> x.g2(1, 2) +>>> x.f3(1, 2, 3) +>>> x.g3(1, 2, 3) +>>> x.f4(1, 2, 3, 4) +>>> x.g4(1, 2, 3, 4) +>>> x.f5(1, 2, 3, 4, 5) +>>> x.g5(1, 2, 3, 4, 5) +>>> x.f6(1, 2, 3, 4, 5, 6) +>>> x.g6(1, 2, 3, 4, 5, 6) +>>> x.f7(1, 2, 3, 4, 5, 6, 7) +>>> x.g7(1, 2, 3, 4, 5, 6, 7) +>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8) +>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8) +>>> x.hash +2155 +""" + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + status = run()[0] + if (status == 0): print "Done." + sys.exit(status) Index: libs/python/test/calling_conventions.py =================================================================== --- libs/python/test/calling_conventions.py (revision 0) +++ libs/python/test/calling_conventions.py (revision 0) @@ -0,0 +1,81 @@ +# Copyright Nicolas Lelong, 2010. Distributed under the Boost +# Software License, Version 1.0 (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +""" +>>> from calling_conventions_ext import * +>>> f_0__cdecl() +17041 +>>> f_1__cdecl(1) +1 +>>> f_2__cdecl(1, 2) +21 +>>> f_3__cdecl(1, 2, 3) +321 +>>> f_4__cdecl(1, 2, 3, 4) +4321 +>>> f_5__cdecl(1, 2, 3, 4, 5) +54321 +>>> f_6__cdecl(1, 2, 3, 4, 5, 6) +654321 +>>> f_7__cdecl(1, 2, 3, 4, 5, 6, 7) +7654321 +>>> f_8__cdecl(1, 2, 3, 4, 5, 6, 7, 8) +87654321 +>>> f_9__cdecl(1, 2, 3, 4, 5, 6, 7, 8, 9) +987654321 +>>> f_0__stdcall() +17041 +>>> f_1__stdcall(1) +1 +>>> f_2__stdcall(1, 2) +21 +>>> f_3__stdcall(1, 2, 3) +321 +>>> f_4__stdcall(1, 2, 3, 4) +4321 +>>> f_5__stdcall(1, 2, 3, 4, 5) +54321 +>>> f_6__stdcall(1, 2, 3, 4, 5, 6) +654321 +>>> f_7__stdcall(1, 2, 3, 4, 5, 6, 7) +7654321 +>>> f_8__stdcall(1, 2, 3, 4, 5, 6, 7, 8) +87654321 +>>> f_9__stdcall(1, 2, 3, 4, 5, 6, 7, 8, 9) +987654321 +>>> f_0__fastcall() +17041 +>>> f_1__fastcall(1) +1 +>>> f_2__fastcall(1, 2) +21 +>>> f_3__fastcall(1, 2, 3) +321 +>>> f_4__fastcall(1, 2, 3, 4) +4321 +>>> f_5__fastcall(1, 2, 3, 4, 5) +54321 +>>> f_6__fastcall(1, 2, 3, 4, 5, 6) +654321 +>>> f_7__fastcall(1, 2, 3, 4, 5, 6, 7) +7654321 +>>> f_8__fastcall(1, 2, 3, 4, 5, 6, 7, 8) +87654321 +>>> f_9__fastcall(1, 2, 3, 4, 5, 6, 7, 8, 9) +987654321 +""" + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + status = run()[0] + if (status == 0): print "Done." + sys.exit(status) Index: libs/python/test/Jamfile.v2 =================================================================== --- libs/python/test/Jamfile.v2 (revision 58712) +++ libs/python/test/Jamfile.v2 (working copy) @@ -184,6 +184,9 @@ # bpl-test bienstman5 ; # } +[ bpl-test calling_conventions ] +[ bpl-test calling_conventions_mf ] + # --- unit tests of library components --- [ compile indirect_traits_test.cpp ] Index: libs/python/doc/v2/configuration.html =================================================================== --- libs/python/doc/v2/configuration.html (revision 58712) +++ libs/python/doc/v2/configuration.html (working copy) @@ -106,6 +106,33 @@ function from being treated as an exported symbol on platforms which support that distinction in-code + + + BOOST_PYTHON_ENABLE_CDECL + + not defined + + If defined, allows functions using the __cdecl + calling convention to be wrapped. + + + + BOOST_PYTHON_ENABLE_STDCALL + + not defined + + If defined, allows functions using the __stdcall + calling convention to be wrapped. + + + + BOOST_PYTHON_ENABLE_FASTCALL + + not defined + + If defined, allows functions using the __fastcall + calling convention to be wrapped. +

Library Defined Implementation