bottlenoselabs / c2cs

Generate C# bindings from a C header.
MIT License
250 stars 18 forks source link

Unity compatible function delegates #67

Closed jazzay closed 2 years ago

jazzay commented 2 years ago

@lithiumtoast are you open to supporting Unity compatible code generation?

If so I will submit a PR that optionally falls back to legacy function delegates as C#9 function pointers are not fully supported in Unity 2021+ yet. I've already implemented this in my own branch.

lithiumtoast commented 2 years ago

I don't use Unity per se; the context is that I come from MonoGame/FNA/XNA.

However, I don't see why not the bindings could not work with Unity. You mention a specific problem of function pointers with Unity; okay, we agree on how to solve this problem.

I used to write C# bindings from hand and I have done it using delegates; e.g. using GetDelegateForFunctionPointer. I had bindings generated using this in the past, but I iterated on this and decided that C# funciton pointers are superior. The reason they are superior is that delegates are objects and thus have allocation memory costs and are tracked by the Garbage Collector. There is also an issue of calling the GetDelegateForFunctionPointer method which requires some setup code; so then there has to be some method the user has to call to set up the bindings. E.g. MyNamespace.MyStaticCLibraryClass.Setup(). However, for generating bindings before C# 9; this would be the only way.

So, I would start to think about "profile"s for generating bindings for specific C# version targets. C# >= 9: Use function pointers; no setup code required. C# < 9: Use delegates for function pointers; requires setup code.

lithiumtoast commented 2 years ago

What do you think @jazzay?

jazzay commented 2 years ago

Yes I agree that C#9 function pointers are superior, however Unity 2021 does not support them fully. I considered the Profile approach (based on language version) however again Unity is special in that it supports some of C# 9.0, but not all of it sadly, making your current implementation not compatible. So I decided to make the flag specific to Unity for now. Are you interested in taking it like this? If so I will send over the PR.

lithiumtoast commented 2 years ago

Yeah.

Does Unity support C# < 9?

jazzay commented 2 years ago

Yes. I will send over a PR.

lithiumtoast commented 2 years ago

I'm contemplating adding this feature in after multi-pass is finished myself if you don't submit a PR. It would require the developer to call a setup / teardown to setup the delegates using GetDelegateForFunctionPointer. The setup / teardown would also be in conjunction with adding support for externed variables where the pointer to the variable would need to be exposed over a get/set property by reading/writing a blittable struct / primitive to the pointer.

jazzay commented 2 years ago

This sounds interesting! Sorry for not pushing a PR yet, I got distracted with other stuff. :) Any idea on timeline for your implementation?

lithiumtoast commented 2 years ago

Soon as I get multipass finished I can take a whack at it. Having issues with Clang cross compilation which is taking longer than expected.

lithiumtoast commented 2 years ago

Going to take a look at your fork https://github.com/jazzay/c2cs/commit/8c2c66c89aef96f0d7a0c4652d9f9abeb472ac5c tomorrow

lithiumtoast commented 2 years ago

@jazzay Let me know if this works for you. If not we can talk about it and see what needs to be tweaked.

jazzay commented 2 years ago

Will take a look. Thanks!