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;
 | 
						|
}
 |