Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve type aliases for function pointers #151

Open
shayded-exe opened this issue Oct 11, 2023 · 2 comments
Open

Improve type aliases for function pointers #151

shayded-exe opened this issue Oct 11, 2023 · 2 comments

Comments

@shayded-exe
Copy link

I'm trying to generate bindings for Nuklear.

It declares the following function pointer:
https://github.com/Immediate-Mode-UI/Nuklear/blob/a14e55f536e0d582930b68b2d3cac7296bae3a25/nuklear.h#L504

typedef nk_bool(*nk_plugin_filter)(const struct nk_text_edit*, nk_rune unicode);

This generates the following C#:

[CNode(Kind = "FunctionPointer")]
[StructLayout(LayoutKind.Sequential)]
public struct FnPtr_NkTextEditPtr_NkRune_CBool
{
    public delegate* unmanaged<nk_text_edit*, nk_rune, CBool> Pointer;
} 

[CNode(Kind = "TypeAlias")]
[StructLayout(LayoutKind.Explicit, Size = 8, Pack = 8)]
public struct nk_plugin_filter
{
    [FieldOffset(0)]
    public FnPtr_NkTextEditPtr_NkRune_CBool Data;

    public static implicit operator FnPtr_NkTextEditPtr_NkRune_CBool(nk_plugin_filter data) => data.Data;
    public static implicit operator nk_plugin_filter(FnPtr_NkTextEditPtr_NkRune_CBool data) => new() { Data = data };
}

It would be nice if the TypeAlias wrapper could be eliminated and the function pointer struct were named using its declared name. Additionally, it should provide a constructor and explicit conversion operator for ease of use.
Like this:

[CNode(Kind = "FunctionPointer")]
[StructLayout(LayoutKind.Sequential)]
public struct nk_plugin_filter
{
    public delegate* unmanaged<nk_text_edit*, nk_rune, CBool> Pointer;

    public nk_plugin_filter(delegate* unmanaged<nk_text_edit*, nk_rune, CBool> pointer) {
	    this.Pointer = pointer;
    }

	public static explicit operator nk_plugin_filter(delegate* unmanaged<nk_text_edit*, nk_rune, CBool> pointer) {
	    return new(pointer);
    }
} 
@lithiumtoast
Copy link
Member

Thanks @shayded-exe for the suggestion.

I was experimenting with this before. The main problem was that wrapping a function pointer in a struct is useful for the case when using delegates for backwards compatibility before .NET 5. I was lazy so I left it wrapped.

You can take a look at the generator class with uses Roslyn to create the struct:

@shayded-exe
Copy link
Author

Ah, makes sense

I've switched to ImGui for now so I can make progress faster, so I'm not using this tool for now, but when I inevitably need bindings for another library I'll make a fork of this to make improvements on.
I've searched around a lot and this is so far the best/easiest option for generating bindings that I've found! If I need to pick it back up I'm happy to contribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants