Hi everyone,

as it will soon be time for me to update the boost version we're using, I once more got my hands into my patch for adding support of various calling conventions to boost.python.

I tried to include the comments that were made a long time ago, and took an approach close to the one used in boost.bind : the defaut is to not support any additional calling conventions. Preprocessor defines allow to enable them :
BOOST_PYTHON_ENABLE_CDECL, BOOST_PYTHON_ENABLE_STDCALL, BOOST_PYTHON_ENABLE_FASTCALL.

I added entries to documentation, and simple unit tests inspired by boost.bind once again.

The new tests should probably not be run on compilers where the calling conventions are irrelevant, but this exceeds both my bjam and compiler specifics knowledge.

The patch attached is made against the current trunk (rev.58712), on my MSCV8 SP1 every boost.python test passes.

Is this mailing list the best route to submit this patch, what more work should be done to get it accepted into trunk ?

Thanks in advance,
best regards,

Nicolas.
Index: boost/python/signature.hpp
===================================================================
--- boost/python/signature.hpp  (revision 58712)
+++ boost/python/signature.hpp  (working copy)
@@ -52,16 +52,23 @@
 //
 //      template <class RT, class T0... class TN>
 //      inline mpl::vector<RT, T0...TN>
-//      get_signature(RT(*)(T0...TN), void* = 0)
+//      get_signature(RT(BOOST_PYTHON_FN_CC *)(T0...TN), void* = 0)
 //      {
 //          return mpl::list<RT, T0...TN>();
 //      }
 //
+//    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 <class RT, class ClassT, class T0... class TN>
 //      inline mpl::vector<RT, ClassT&, T0...TN>
-//      get_signature(RT(ClassT::*)(T0...TN) cv))
+//      get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv))
 //      {
 //          return mpl::list<RT, ClassT&, T0...TN>();
 //      }
@@ -72,7 +79,7 @@
 //        , typename most_derived<Target, ClassT>::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<RT, ClassT&, T0...TN>();
 //      }
@@ -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, <boost/python/signature.hpp>))
 
 #  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, <boost/python/signature.hpp>))
+
+#   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, <boost/python/signature.hpp>))
+
+#   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, <boost/python/signature.hpp>))
+
+#   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 <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <boost/python.hpp>
+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 <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <boost/python.hpp>
+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>("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</td>
       </tr>
+
+      <tr>
+        <td valign="top"><code>BOOST_PYTHON_ENABLE_CDECL</code></td>
+
+        <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+        <td valign="top">If defined, allows functions using the <code>__cdecl
+        </code> calling convention to be wrapped.</td>
+      </tr>
+
+      <tr>
+        <td valign="top"><code>BOOST_PYTHON_ENABLE_STDCALL</code></td>
+
+        <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+        <td valign="top">If defined, allows functions using the <code>__stdcall
+        </code> calling convention to be wrapped.</td>
+      </tr>
+
+      <tr>
+        <td valign="top"><code>BOOST_PYTHON_ENABLE_FASTCALL</code></td>
+
+        <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+        <td valign="top">If defined, allows functions using the 
<code>__fastcall
+        </code> calling convention to be wrapped.</td>
+      </tr>
     </table>
 
     <h2><a name="lib-defined-impl"></a>Library Defined Implementation
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to