Closed rokups closed 2 years ago
Would probably need a bit of extra commentary + updating docs/MetadataFormat Can you also provide some concrete example of where this is going to be useful?
pybind11 is pure-c++ library that implements bindings to python. We do roughly this:
#include <pybind11/pybind11.h>
namespace cimgui { extern "C" {
#include "c_generated/cimgui.h"
#include "c_generated/cimgui_internal.h"
} }
#include <imgui.h>
#include <imgui_internal.h>
#include "typecasters.hpp"
namespace py = pybind11;
void bind_funcs(pybind11::module_& m)
{
m.def("CreateContextEx", &ImGui::CreateContext, py::return_value_policy::reference);
m.def("DestroyContextEx", &ImGui::DestroyContext, py::return_value_policy::automatic);
m.def("GetCurrentContext", &ImGui::GetCurrentContext, py::return_value_policy::reference);
m.def("SetCurrentContext", &ImGui::SetCurrentContext, py::return_value_policy::automatic);
m.def("GetIO", &ImGui::GetIO, py::return_value_policy::reference);
m.def("GetStyle", &ImGui::GetStyle, py::return_value_policy::reference);
m.def("NewFrame", &ImGui::NewFrame, py::return_value_policy::automatic);
m.def("EndFrame", &ImGui::EndFrame, py::return_value_policy::automatic);
m.def("Render", &ImGui::Render, py::return_value_policy::automatic);
// And many more...
}
It feeds existing C++ functions to pyblind11 for bindings to be generated. Since JSON also contains generated functions that arent available outside of cimgui i needed to know which functions correspond to the original and which ones are newly injected so i can avoid binding injected functions (python can support default arguments therefore there is no need to wrap these helper functions).
Hm... I'm confused as to what counts as "synthetic" in this case - I think I must be missing something because I keep thinking "if you can feed C++ functions to pybind11 then why is Dear Bindings needed at all?". Is what you're looking for metadata for the original C++ API rather than the newly-generated C-one, maybe?
CIMGUI_API bool ImGui_DragIntEx(const char* label, int* v, float v_speed /* = 1.0f */, int v_min /* = 0 */, int v_max /* = 0 */, const char* format /* = "%d" */, ImGuiSliderFlags flags /* = 0 */); // If v_min >= v_max we have no bound
CIMGUI_API bool ImGui_DragInt(const char* label, int* v); // Implied v_speed = 1.0f, v_min = 0, v_max = 0, format = "%d", flags = 0
This would be an example of synthetic vs non-synthetic. ImGui_DragIntEx
is non-synthetic because it corresponds to original ImGui::DragInt
.
ImGui_DragInt
on the other hand has no exact counterpart on C++ side and was generated - it is synthetic.
if you can feed C++ functions to pybind11 then why is Dear Bindings needed at all?
Forgot that one. Dear Bindings produces a very useful JSON with all the API, including argument types and what not. Using this JSON is very convenient for generating bindings with pybind11.
Ah, gotcha - I understand now!
So in the case of ImGui_DragInt()
at least, you can tell them apart by looking at is_default_argument_helper
, which is true
in the case of functions that have been generated as ways to substitute for default arguments. Similarly is_manual_helper
is true on manually-added helper functions (just ImVector_Construct
and ImVector_Destruct
at present).
Off the top of my head I'm drawing a blank on other functions that get added programmatically to the API, so I think that just ORing those two together may get you the result you want, but I may well be forgetting something... do you know of another case I've missed that needs tagging?
I did not realize i could use is_default_argument_helper
+is_manual_helper
. Sounds like they cover this usecase already.
do you know of another case I've missed that needs tagging?
Not at the moment. I did not do that much work on python bindings. If i stumble upon something i will surely let you know 👍🏻
Seems like we can close this PR then, thanks! 🙏🏻
I came to a need of this when i tried to consume API json file directly and write a generator that outputs pybind11 code to produce python bindings. In such case it is required to know which functions actually exist in the library and should be wrapped and which ones are generated. Due to how pybind11 works there is no need to wrap a C api and i can feed C++ api to it directly. I am not sure if this is complete/correct so please review.