8000 Add macros to set calling conventions for callbacks. by seanmiddleditch · Pull Request #904 · ocornut/imgui · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add macros to set calling conventions for callbacks. #904

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

seanmiddleditch
Copy link
Contributor

Required to successfully link when compiling with non-default calling conventions.

e.g., if the hosting app is compiled with /Gv to use the __vectorcall calling convention by default, which is sometimes a huge performance improvement, they will not be able to call imgui functions. Compiling imgui itself with /Gv does not work since system callbacks also need to be marked.

This change makes a single universal IMGUI_CALLBACK macro for marking up all callbacks, typically to __cdecl. If there is a desire to allow imgui callbacks to have custom calling conventions (if there is ever a high-volume callback, for instance) then there may need to be separate macros for CRT callbacks and imgui callbacks.

This change also modified an stb header that uses qsort and hence needs to set calling convention. That change could be pushed back to stb if there is a desire to avoid patches over stb.

Required to successfully link when compiling with non-default calling conventions.
Copy link
Owner
@ocornut ocornut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how /Gv works, when you say:

they will not be able to call imgui functions

Do you mean none of the imgui functions can be called? or is just that your functions with default settings won't work as imgui as callbacks?

Wouldn't it saner and simplier if your app defined the few callbacks it needs for imgui as __cdecl?

#else
#define IMGUI_CALLBACK
#endif

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confused about how this blocks work, wouldn't statement in the else override whatever the user has specified?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty define result in replacement with nothing.

aka static const char* IMGUI_CALLBACK GetClipboardTextFn_DefaultImpl(void* user_data); turns into static const char* GetClipboardTextFn_DefaultImpl(void* user_data); letting the default calling conv take over.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but isn't the point that the user might want to define IMGUI_CALLBACK to something that's not your default?

Shouldn't the correct test should just be:

#ifndef IMGUI_CALLBACK
#define IMGUI_CALLBACK
#endif

Let the user do what they want and not involve _WIN32 there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're on _WIN32, __cdecl is the correct default. It's the Windows standard callback ABI that is used by all callbacks in Microsoft's headers (they have a CALLBACK macro that does the same thing here). If you decide to use a different ABI for callbacks on Windows, several of the default callbacks in imgui will become illegal.

This whole thing is basically a Windows-ism, so it really does make since to only do this for _WIN32, and even supporting non-default ABIs like we do is more of a super advanced need that could probably just be removed.

A large and ever better fix here would be for imgui to follow the standard Windows practice of using a macro to declare the ABI for every non-inline function so that imgui is not affected by default ABI settings. That would allow imgui and the host app to be compiled with different defaults and still have everything link and run. That is not essential to fixing the bug this PR is address, though.

@seanmiddleditch
Copy link
Contributor Author

Do you mean none of the imgui functions can be called?

In the case that the host app is compiled with /Gv and imgui is in a static library compiled with a different default ABI, then no, you not be able to invoke any imgui function (and will get a linker error because the ABI affects mangling).

If you compile imgui with /Gv then the standard imgui functions are invokable but callbacks become problematic due to a mixture of system-provided functions and user-provided functions used as callbacks (e.g., the IME and clipboard callbacks, among others, iirc). The system-provided functions on Windows will always use __cdecl but user-provided ones will only do so if they explicitly set it as such. imgui could use wrappers around all system-provided functions to avoid ABI issues, but that adds some library bloat and is cumbersome.

Since tossing __cdecl into user code makes said code unportable, the common approach here is to use a macro on all callback functions that expands to __cdecl on Windows and expands to nothing on other platforms.

@ocornut
Copy link
Owner
ocornut commented Mar 1, 2018

Hello @seanmiddleditch, and my apologies for keeping that PR dangling for so long.

I recently merged in #1611 which seems to tackle (partly) the same issue but only changed the 3 functions (there was 2 at the time of your PR) that are called by e.g. libc qsort.

I am a little confused however about the extra changes affecting e.g. GetClipboardTextFn, SetClipboardTextFn, ImeSetInputScreenPosFn. Just to clarify - if I understand correctly, the extra changes are necessary only to allow compiling your app code (which would include imgui.h and potentially assign to those function pointers) and imgui.cpp with different calling conventions? Is that correct? If the full app + imgui are compiled with the same calling convention, e.g. /Gv it doesn't seem to be a problem? (since we fixed the function called by qsort in #1611).

@seanmiddleditch
Copy link
Contributor Author

Hi, yeah it would affect things if calling connections differ. Not my use case but still a potentially valid one to consider.

@ocornut
Copy link
Owner
ocornut commented Apr 12, 2020

Hello Sean,
Any reason for closing this?

@seanmiddleditch
Copy link
Contributor Author

@ocornut - ah, don't think I did that intentionally, and never got through my github notifications backlog until now to see this question :( -- cool to reopen?

@ocornut ocornut reopened this Aug 15, 2020
@ocornut
Copy link
Owner
ocornut commented Aug 15, 2020

Sure!

@seanmiddleditch
Copy link
Contributor Author

Cool, thanks. It's been a few years, but... are you on board with the general gist of fixes? I can get this updated to the latest master.

Since you're on Github Actions now I can also add a test specifically for the case I ran into with using /Gv as a global compilation option, as well as a test with mixing/matching the calling conventions between imgui and test code.

@ocornut ocornut force-pushed the master branch 2 times, most recently from 0c1e5bd to bb6a60b Compare August 27, 2021 19:10
@ocornut ocornut force-pushed the master branch 2 times, most recently from 8b83e0a to d735066 Compare December 13, 2021 11:31
@ocornut ocornut force-pushed the master branch 2 times, most recently from b3b85d8 to 0755767 Compare January 17, 2022 14:21
@ocornut ocornut force-pushed the master branch 3 times, most recently from c817acb to 8d39063 Compare February 15, 2022 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0