Skip to content

Bindgen generates wrong bingings for function #1778

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

Closed
TheRadioGuy opened this issue May 9, 2020 · 9 comments
Closed

Bindgen generates wrong bingings for function #1778

TheRadioGuy opened this issue May 9, 2020 · 9 comments

Comments

@TheRadioGuy
Copy link

Input C/C++ Header

    typedef
        _Function_class_(EVT_VIGEM_X360_NOTIFICATION)
        VOID CALLBACK
        EVT_VIGEM_X360_NOTIFICATION(
            PVIGEM_CLIENT Client,
            PVIGEM_TARGET Target,
            UCHAR LargeMotor,
            UCHAR SmallMotor,
            UCHAR LedNumber,
            LPVOID UserData
        );

    typedef EVT_VIGEM_X360_NOTIFICATION *PFN_VIGEM_X360_NOTIFICATION;

Bindgen Invocation

$ bindgen .\ViGEmClient.cpp -o mod.rs  --whitelist-function 'vigem_.*' 

Actual Results

pub type PFN_VIGEM_X360_NOTIFICATION = ::std::option::Option<unsafe extern "C" fn()>;

Expected Results

In rust bindings, there's function with no params, but as we can see in CPP code - there's a lot of params.

By the way, bindings
headers

@TheRadioGuy
Copy link
Author

And there's no EVT_VIGEM_X360_NOTIFICATION in bindings :(

@emilio
Copy link
Contributor

emilio commented May 13, 2020

This seems similar to some other issues where libclang doesn't expose the arguments probably, then bindgen tries to guess from the AST, but it still fails because of macros.

Can you paste a definition of EVT_VIGEM_X360_NOTIFICATION and the other macros in use here? Ideally a chunk of code that reproduces the issue entirely is the most helpful.

Thanks for filing!

@emilio
Copy link
Contributor

emilio commented May 13, 2020

Ah, apparently _Function_class_ is some sort of VC++ annotation. TIL

@emilio
Copy link
Contributor

emilio commented May 13, 2020

You need to find where CALLBACK and VOID are defined and so on.

@TheRadioGuy
Copy link
Author

There's void.
and I could not find CALLBACK definition

@emilio
Copy link
Contributor

emilio commented May 14, 2020

No, I know what void is, this is about VOID (uppercase). The definition is probably in one of the windows headers.

It seems CALLBACK is just __stdcall.

@emilio
Copy link
Contributor

emilio commented May 14, 2020

So something like this should do:

#define VOID void
#define CALLBACK __stdcall
#define UCHAR unsigned char

typedef
    VOID CALLBACK
    EVT_VIGEM_X360_NOTIFICATION(
        void* Client,
        void* Target,
        UCHAR LargeMotor,
        UCHAR SmallMotor,
        UCHAR LedNumber,
        void* UserData
    );

typedef EVT_VIGEM_X360_NOTIFICATION *PFN_VIGEM_X360_NOTIFICATION;

@emilio
Copy link
Contributor

emilio commented May 14, 2020

This is a libclang bug, https://bugs.llvm.org/show_bug.cgi?id=45919.

But we can workaround it in bindgen to some extent.

emilio added a commit that referenced this issue May 14, 2020
…cls.

It seems libclang sometimes doesn't expose the right paramdecl cursors.

This should be reported upstream, but it's easy enough to workaround. It
loses the parameter names which is a bit unfortunate but...

Fixes #1778
@emilio emilio closed this as completed in b1a1ebc May 14, 2020
@TheRadioGuy
Copy link
Author

I have not checked it yet, but thank you!

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

No branches or pull requests

2 participants