m1.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. // Copyright David Abrahams 2001.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #include <boost/python/def.hpp>
  6. #include <boost/python/module.hpp>
  7. #include <boost/python/class.hpp>
  8. #include <boost/python/lvalue_from_pytype.hpp>
  9. #include <boost/python/copy_const_reference.hpp>
  10. #include <boost/python/return_value_policy.hpp>
  11. #include <boost/python/to_python_converter.hpp>
  12. #include <boost/python/errors.hpp>
  13. #include <boost/python/manage_new_object.hpp>
  14. #include <boost/python/converter/pytype_function.hpp>
  15. #include <string.h>
  16. #include "simple_type.hpp"
  17. #include "complicated.hpp"
  18. // Declare some straightforward extension types
  19. extern "C" void
  20. dealloc(PyObject* self)
  21. {
  22. PyObject_Del(self);
  23. }
  24. // Noddy is a type we got from one of the Python sample files
  25. struct NoddyObject : PyObject
  26. {
  27. int x;
  28. };
  29. PyTypeObject NoddyType = {
  30. PyVarObject_HEAD_INIT(NULL, 0)
  31. const_cast<char*>("Noddy"),
  32. sizeof(NoddyObject),
  33. 0,
  34. dealloc, /* tp_dealloc */
  35. 0, /* tp_print */
  36. 0, /* tp_getattr */
  37. 0, /* tp_setattr */
  38. 0, /* tp_compare */
  39. 0, /* tp_repr */
  40. 0, /* tp_as_number */
  41. 0, /* tp_as_sequence */
  42. 0, /* tp_as_mapping */
  43. 0, /* tp_hash */
  44. 0, /* tp_call */
  45. 0, /* tp_str */
  46. 0, /* tp_getattro */
  47. 0, /* tp_setattro */
  48. 0, /* tp_as_buffer */
  49. 0, /* tp_flags */
  50. 0, /* tp_doc */
  51. 0, /* tp_traverse */
  52. 0, /* tp_clear */
  53. 0, /* tp_richcompare */
  54. 0, /* tp_weaklistoffset */
  55. 0, /* tp_iter */
  56. 0, /* tp_iternext */
  57. 0, /* tp_methods */
  58. 0, /* tp_members */
  59. 0, /* tp_getset */
  60. 0, /* tp_base */
  61. 0, /* tp_dict */
  62. 0, /* tp_descr_get */
  63. 0, /* tp_descr_set */
  64. 0, /* tp_dictoffset */
  65. 0, /* tp_init */
  66. 0, /* tp_alloc */
  67. 0, /* tp_new */
  68. 0, /* tp_free */
  69. 0, /* tp_is_gc */
  70. 0, /* tp_bases */
  71. 0, /* tp_mro */
  72. 0, /* tp_cache */
  73. 0, /* tp_subclasses */
  74. 0, /* tp_weaklist */
  75. #if PYTHON_API_VERSION >= 1012
  76. 0 /* tp_del */
  77. #endif
  78. };
  79. // Create a Noddy containing 42
  80. PyObject* new_noddy()
  81. {
  82. NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType);
  83. noddy->x = 42;
  84. return (PyObject*)noddy;
  85. }
  86. // Simple is a wrapper around a struct simple, which just contains a char*
  87. struct SimpleObject
  88. {
  89. PyObject_HEAD
  90. simple x;
  91. };
  92. struct extract_simple_object
  93. {
  94. static simple& execute(SimpleObject& o) { return o.x; }
  95. };
  96. PyTypeObject SimpleType = {
  97. PyVarObject_HEAD_INIT(NULL, 0)
  98. const_cast<char*>("Simple"),
  99. sizeof(SimpleObject),
  100. 0,
  101. dealloc, /* tp_dealloc */
  102. 0, /* tp_print */
  103. 0, /* tp_getattr */
  104. 0, /* tp_setattr */
  105. 0, /* tp_compare */
  106. 0, /* tp_repr */
  107. 0, /* tp_as_number */
  108. 0, /* tp_as_sequence */
  109. 0, /* tp_as_mapping */
  110. 0, /* tp_hash */
  111. 0, /* tp_call */
  112. 0, /* tp_str */
  113. 0, /* tp_getattro */
  114. 0, /* tp_setattro */
  115. 0, /* tp_as_buffer */
  116. 0, /* tp_flags */
  117. 0, /* tp_doc */
  118. 0, /* tp_traverse */
  119. 0, /* tp_clear */
  120. 0, /* tp_richcompare */
  121. 0, /* tp_weaklistoffset */
  122. 0, /* tp_iter */
  123. 0, /* tp_iternext */
  124. 0, /* tp_methods */
  125. 0, /* tp_members */
  126. 0, /* tp_getset */
  127. 0, /* tp_base */
  128. 0, /* tp_dict */
  129. 0, /* tp_descr_get */
  130. 0, /* tp_descr_set */
  131. 0, /* tp_dictoffset */
  132. 0, /* tp_init */
  133. 0, /* tp_alloc */
  134. 0, /* tp_new */
  135. 0, /* tp_free */
  136. 0, /* tp_is_gc */
  137. 0, /* tp_bases */
  138. 0, /* tp_mro */
  139. 0, /* tp_cache */
  140. 0, /* tp_subclasses */
  141. 0, /* tp_weaklist */
  142. #if PYTHON_API_VERSION >= 1012
  143. 0 /* tp_del */
  144. #endif
  145. };
  146. // Create a Simple containing "hello, world"
  147. PyObject* new_simple()
  148. {
  149. SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
  150. simple->x.s = const_cast<char*>("hello, world");
  151. return (PyObject*)simple;
  152. }
  153. //
  154. // Declare some wrappers/unwrappers to test the low-level conversion
  155. // mechanism.
  156. //
  157. using boost::python::to_python_converter;
  158. // Wrap a simple by copying it into a Simple
  159. struct simple_to_python
  160. : to_python_converter<simple, simple_to_python, true>
  161. //, boost::python::converter::wrap_pytype<&SimpleType>
  162. {
  163. static PyObject* convert(simple const& x)
  164. {
  165. SimpleObject* p = PyObject_New(SimpleObject, &SimpleType);
  166. p->x = x;
  167. return (PyObject*)p;
  168. }
  169. static PyTypeObject const *get_pytype(){return &SimpleType; }
  170. };
  171. struct int_from_noddy
  172. {
  173. static int& execute(NoddyObject& p)
  174. {
  175. return p.x;
  176. }
  177. };
  178. //
  179. // Some C++ functions to expose to Python
  180. //
  181. // Returns the length of s's held string
  182. int f(simple const& s)
  183. {
  184. return strlen(s.s);
  185. }
  186. int f_mutable_ref(simple& s)
  187. {
  188. return strlen(s.s);
  189. }
  190. int f_mutable_ptr(simple* s)
  191. {
  192. return strlen(s->s);
  193. }
  194. int f_const_ptr(simple const* s)
  195. {
  196. return strlen(s->s);
  197. }
  198. int f2(SimpleObject const& s)
  199. {
  200. return strlen(s.x.s);
  201. }
  202. // A trivial passthru function for simple objects
  203. simple const& g(simple const& x)
  204. {
  205. return x;
  206. }
  207. struct A
  208. {
  209. A() : x(0) {}
  210. virtual ~A() {}
  211. char const* name() { return "A"; }
  212. int x;
  213. };
  214. struct B : A
  215. {
  216. B() : x(1) {}
  217. static char const* name(B*) { return "B"; }
  218. int x;
  219. };
  220. struct C : A
  221. {
  222. C() : x(2) {}
  223. char const* name() { return "C"; }
  224. virtual ~C() {}
  225. int x;
  226. };
  227. struct D : B, C
  228. {
  229. D() : x(3) {}
  230. char const* name() { return "D"; }
  231. int x;
  232. };
  233. A take_a(A const& a) { return a; }
  234. B take_b(B& b) { return b; }
  235. C take_c(C* c) { return *c; }
  236. D take_d(D* const& d) { return *d; }
  237. D take_d_shared_ptr(boost::shared_ptr<D> d) { return *d; }
  238. boost::shared_ptr<A> d_factory() { return boost::shared_ptr<B>(new D); }
  239. struct Unregistered {};
  240. Unregistered make_unregistered(int) { return Unregistered(); }
  241. Unregistered* make_unregistered2(int) { return new Unregistered; }
  242. BOOST_PYTHON_MODULE(m1)
  243. {
  244. using namespace boost::python;
  245. using boost::shared_ptr;
  246. simple_to_python();
  247. lvalue_from_pytype<int_from_noddy,&NoddyType>();
  248. lvalue_from_pytype<
  249. #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters
  250. extract_member<SimpleObject, simple, &SimpleObject::x>
  251. #else
  252. extract_simple_object
  253. #endif
  254. , &SimpleType
  255. >();
  256. lvalue_from_pytype<extract_identity<SimpleObject>,&SimpleType>();
  257. def("new_noddy", new_noddy);
  258. def("new_simple", new_simple);
  259. def("make_unregistered", make_unregistered);
  260. def("make_unregistered2", make_unregistered2, return_value_policy<manage_new_object>());
  261. // Expose f() in all its variations
  262. def("f", f);
  263. def("f_mutable_ref", f_mutable_ref);
  264. def("f_mutable_ptr", f_mutable_ptr);
  265. def("f_const_ptr", f_const_ptr);
  266. def("f2", f2);
  267. // Expose g()
  268. def("g", g , return_value_policy<copy_const_reference>()
  269. );
  270. def("take_a", take_a);
  271. def("take_b", take_b);
  272. def("take_c", take_c);
  273. def("take_d", take_d);
  274. def("take_d_shared_ptr", take_d_shared_ptr);
  275. def("d_factory", d_factory);
  276. class_<A, shared_ptr<A> >("A")
  277. .def("name", &A::name)
  278. ;
  279. // sequence points don't ensure that "A" is constructed before "B"
  280. // or "C" below if we make them part of the same chain
  281. class_<B,bases<A> >("B")
  282. .def("name", &B::name)
  283. ;
  284. class_<C,bases<A> >("C")
  285. .def("name", &C::name)
  286. ;
  287. class_<D, bases<B,C> >("D")
  288. .def("name", &D::name)
  289. ;
  290. class_<complicated>("complicated",
  291. init<simple const&,int>())
  292. .def(init<simple const&>())
  293. .def("get_n", &complicated::get_n)
  294. ;
  295. }
  296. #include "module_tail.cpp"