ThePhD / sol2

Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:
http://sol2.rtfd.io/
MIT License
4.06k stars 492 forks source link

Handling opaque C pointers #1602

Open deadlocklogic opened 1 month ago

deadlocklogic commented 1 month ago

How to properly handle opaque C pointers? They are very popular in many C libraries. Right now I doing so, consider glfw where GLFWwindow and GLFWmonitor are opaque pointers. Consider binding:

GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);

Binding it like:

state["glfwCreateWindow"] = &glfwCreateWindow;

Fails to compile with incomplete type 'GLFWwindow' used in type trait expression.

So I am binding it while introducing a proxy holder like so:

template <typename T = void>
struct OpaquePtr {
  T *ptr = nullptr;
};

state["glfwCreateWindow"] = [](int width, int height, char const* title, OpaquePtr<GLFWmonitor>* monitor, OpaquePtr<GLFWwindow>* share) {
    return OpaquePtr<GLFWwindow> { glfwCreateWindow(width, height, title, monitor ? monitor->ptr : nullptr, share ? share->ptr : nullptr) };
};

And I have to modify all the related API to afford the newly introduced proxy holder OpaquePtr for incomplete types.

I completely understand that sol2 needs complete types so it can participate in its type system so it can catch type mismatch errors instead of letting the program crash. @ThePhD Is this the best of what could be done or better solutions exist? Thanks.

Edit:

Actually sol is trying to check against is_base_of_v trait at some point in sol::is_container and sol::is_lua_reference. So specializing sol::is_lua_reference<TYPE> : std::false_type with the opaque type solves the problem. Is it worth introducing a new traits is_c_type?