-
-
Notifications
You must be signed in to change notification settings - Fork 76
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
Strong typed Wh_SetFunctionHook #85
Comments
Nice. In Windhawk v1.3, I added the |
Do you have an idea for an upgrade path? My recent mod has this function inline defined, but it would be a bit of an issue if the mod only works on the old or the new version: Or is there a mod option that tells which Windhawk version it minimally needs? One idea would be that there is a define that can be checked, and if that's set I can include |
Depending on how readable the error is, it might make sense to add a comment or something near that prototype explaining that compile errors on it mean that one of the prototypes is wrong btw. (Considering that Windhawk might also be used by people that are not a developer by profession ;) ) |
I'm not sure what you mean by an upgrade path, but here's how it currently impacts users and developers: Users: Trying to install an incompatible mod will result in a "Compilation failed" message. That's not optimal, as there's no indication for the error reason and a user can't know that updating Windhawk will solve it. An average user might not even know what compilation means. Newer Windhawk versions show a more useful message similar to "Compilation failed, you might need to update Windhawk". Developers: The situation here isn't optimal either. For a developer using the latest version of Windhawk, it's difficult to know how backwards compatible the code is, and checking it is tedious. For my mods, if I see that I use newer features, I try to add the required Windhawk version in the readme or near the relevant setting, but it's easy to miss. That's the main reason I didn't document P.S. Even your simple regedit mod requires Windhawk v1.2 due to the usage of the There are various things that can be done to improve this, like running GitHub actions to verify compatibility and adding a minimal Windhawk version to metadata, which I might look at in the future.
I did something similar with the volume control mod: In that case, the header is only needed for a secondary feature. So the mod is compatible with older Windhawk versions, but this feature won't work. Even worse, it won't work even after Windhawk is updated unless the mod is recompiled. So now, in hindsight, I don't think that it was a good idea. But you're talking about a case in which the main mod functionality requires the header. In this case, why would you conditionally include the header and conditionally inline? You can just inline the implementation and support all Windhawk versions. Many of my mods have a function to load and cache symbols, it's about 200 lines long and it's ugly to copy paste it every time, but I do it for backwards compatibility. That was the main motivation for
That's a good idea, perhaps a |
I'm working on a new Windhawk version and looking into including template <typename Prototype>
BOOL Wh_SetFunctionHookT(Prototype* targetFunction,
Prototype* hookFunction,
Prototype** originalFunction) {
return Wh_SetFunctionHook(reinterpret_cast<void*>(targetFunction),
reinterpret_cast<void*>(hookFunction),
reinterpret_cast<void**>(originalFunction));
} It's very similar to your variant but imposes slightly more constraints.
I tried improving the error messages. One option I experimented with is this: template <typename P1, typename P2, typename P3>
BOOL Wh_SetFunctionHookT(P1 targetFunction,
P2 hookFunction,
P3* originalFunction) {
static_assert(std::is_same<P1, P2>::value, "Hook function prototype doesn't match the target function");
static_assert(std::is_same<P1, P3>::value, "Original function prototype doesn't match the target function");
return Wh_SetFunctionHook((void*)targetFunction, (void*)hookFunction,
(void**)originalFunction);
} The error is noisy but slightly better than the first version. The downside is that the IDE doesn't mark the call site with an error, which is only detected when compiling, so I think it's not worth it. I also tried concepts, it works but there's no way to use a custom message so it's not really better than the first version. If you have any other ideas, let me know. Otherwise I'll go with my first version. |
Seems like a nice solution indeed! |
Version 1.4 includes |
For my own code I like to use a strong-typed
Wh_SetFunctionHook
wrapper:When used with
decltype
and winapi functions, this allows to detect prototype mismatches:This will compile just fine:
This won't compile (note the mismatched return type):
The text was updated successfully, but these errors were encountered: