I thought the standard way to use ETW is by generating code from a manifest file with Message Compiler. Presumably it takes care of all this boilerplate? You're right though, that's a weird API. It'd be interesting to learn the process behind its design.
This is the way I've done it. Which boils the problem down to an init call and a call per event. I dislike the code generated bindings though - is there a more... data driven alternative that's good?
I've got a simple event API where I have an event type identifier, and some basic data. Which I then need to pipe to some third party junk that listens to ETW events. To do this, I have to:
1) Manually map hundreds of event types to code generated ones, and update this mapping every time new events are added... or do a massive N:1 mapping... which is totally against the grain of the intended usage of the third party junk (although appears workable for the moment.)
2) Wrap every ETW event type with callbacks, and the init macro with a stub to allow callbacks, such that I may target the two "identically" configured endpoints... each with their own manifest and autogenerated header.
3) Wrap every ETW invoke with #ifdef s to limit them to the 1 of my 3 platforms they work on.
It's quite ugly compared to the equivalents of the other 2 platforms.