104 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
| // Copyright (c) 2024 The pybind Community.
 | |
| 
 | |
| // THIS MUST STAY AT THE TOP!
 | |
| #include <pybind11/pybind11.h> // EXCLUSIVELY for PYBIND11_PLATFORM_ABI_ID
 | |
| // Potential future direction to maximize reusability:
 | |
| // (e.g. for use from SWIG, Cython, PyCLIF, nanobind):
 | |
| //     #include <pybind11/compat/platform_abi_id.h>
 | |
| // This would only depend on:
 | |
| //     1. A C++ compiler, WITHOUT requiring -fexceptions.
 | |
| //     2. Python.h
 | |
| 
 | |
| #include "test_cpp_conduit_traveler_types.h"
 | |
| 
 | |
| #include <Python.h>
 | |
| #include <typeinfo>
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| void *get_cpp_conduit_void_ptr(PyObject *py_obj, const std::type_info *cpp_type_info) {
 | |
|     PyObject *cpp_type_info_capsule
 | |
|         = PyCapsule_New(const_cast<void *>(static_cast<const void *>(cpp_type_info)),
 | |
|                         typeid(std::type_info).name(),
 | |
|                         nullptr);
 | |
|     if (cpp_type_info_capsule == nullptr) {
 | |
|         return nullptr;
 | |
|     }
 | |
|     PyObject *cpp_conduit = PyObject_CallMethod(py_obj,
 | |
|                                                 "_pybind11_conduit_v1_",
 | |
|                                                 "yOy",
 | |
|                                                 PYBIND11_PLATFORM_ABI_ID,
 | |
|                                                 cpp_type_info_capsule,
 | |
|                                                 "raw_pointer_ephemeral");
 | |
|     Py_DECREF(cpp_type_info_capsule);
 | |
|     if (cpp_conduit == nullptr) {
 | |
|         return nullptr;
 | |
|     }
 | |
|     void *void_ptr = PyCapsule_GetPointer(cpp_conduit, cpp_type_info->name());
 | |
|     Py_DECREF(cpp_conduit);
 | |
|     if (PyErr_Occurred()) {
 | |
|         return nullptr;
 | |
|     }
 | |
|     return void_ptr;
 | |
| }
 | |
| 
 | |
| template <typename T>
 | |
| T *get_cpp_conduit_type_ptr(PyObject *py_obj) {
 | |
|     void *void_ptr = get_cpp_conduit_void_ptr(py_obj, &typeid(T));
 | |
|     if (void_ptr == nullptr) {
 | |
|         return nullptr;
 | |
|     }
 | |
|     return static_cast<T *>(void_ptr);
 | |
| }
 | |
| 
 | |
| extern "C" PyObject *wrapGetLuggage(PyObject * /*self*/, PyObject *traveler) {
 | |
|     const auto *cpp_traveler
 | |
|         = get_cpp_conduit_type_ptr<pybind11_tests::test_cpp_conduit::Traveler>(traveler);
 | |
|     if (cpp_traveler == nullptr) {
 | |
|         return nullptr;
 | |
|     }
 | |
|     return PyUnicode_FromString(cpp_traveler->luggage.c_str());
 | |
| }
 | |
| 
 | |
| extern "C" PyObject *wrapGetPoints(PyObject * /*self*/, PyObject *premium_traveler) {
 | |
|     const auto *cpp_premium_traveler
 | |
|         = get_cpp_conduit_type_ptr<pybind11_tests::test_cpp_conduit::PremiumTraveler>(
 | |
|             premium_traveler);
 | |
|     if (cpp_premium_traveler == nullptr) {
 | |
|         return nullptr;
 | |
|     }
 | |
|     return PyLong_FromLong(static_cast<long>(cpp_premium_traveler->points));
 | |
| }
 | |
| 
 | |
| PyMethodDef ThisMethodDef[] = {{"GetLuggage", wrapGetLuggage, METH_O, nullptr},
 | |
|                                {"GetPoints", wrapGetPoints, METH_O, nullptr},
 | |
|                                {nullptr, nullptr, 0, nullptr}};
 | |
| 
 | |
| struct PyModuleDef ThisModuleDef = {
 | |
|     PyModuleDef_HEAD_INIT, // m_base
 | |
|     "exo_planet_c_api",    // m_name
 | |
|     nullptr,               // m_doc
 | |
|     -1,                    // m_size
 | |
|     ThisMethodDef,         // m_methods
 | |
|     nullptr,               // m_slots
 | |
|     nullptr,               // m_traverse
 | |
|     nullptr,               // m_clear
 | |
|     nullptr                // m_free
 | |
| };
 | |
| 
 | |
| } // namespace
 | |
| 
 | |
| #if defined(WIN32) || defined(_WIN32)
 | |
| #    define EXO_PLANET_C_API_EXPORT __declspec(dllexport)
 | |
| #else
 | |
| #    define EXO_PLANET_C_API_EXPORT __attribute__((visibility("default")))
 | |
| #endif
 | |
| 
 | |
| extern "C" EXO_PLANET_C_API_EXPORT PyObject *PyInit_exo_planet_c_api() {
 | |
|     PyObject *m = PyModule_Create(&ThisModuleDef);
 | |
|     if (m == nullptr) {
 | |
|         return nullptr;
 | |
|     }
 | |
|     return m;
 | |
| }
 |