mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-28 16:11:59 +00:00
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;
|
||
|
}
|