mirror of https://github.com/pybind/pybind11
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.5 KiB
103 lines
3.5 KiB
// 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; |
|
}
|
|
|