Replies: 2 comments 6 replies
-
I had the same confusion, but had following error: project architecture was "Any CPU" and nothing was generated. Setting this to e.g. x64 generates the needed code. But I agree: this does not align well with the given API from pinvoke.net and using unsafe code. Definitive room for improvement 😉 For example:
Well, nothing that couldn't be solved on users end, e.g. with Rider you have easy access to the generated files. It took me a little more time to figure out all parts from the signature of (User32) But I like this approach of generating only the needed stuff, and reduce the overhaul of unused APIs... |
Beta Was this translation helpful? Give feedback.
-
Thank you for your feedback, @xyzzer. Keep it coming. Some specific responses below:
Sorry about that. I think pinvoke.net will be cognitively simpler to grasp than CsWin32 for a while yet, while C# folks get more accustomed to source generators. Copy and paste code from the internet has been around for decades vs. source generators for only a few years. That said, my struggle with pinvoke.net has been poor or inconsistent quality and the need to copy and paste many snippets in order to get all the types declared. And when I'm using many definitions from pinvoke.net, I find they were never meant to work together and I had to unify types, etc.
The reason this didn't work is because in C# there is no such thing as a method without a type, and Ctrl+. never adds type names in front of methods. Had you typed Ctrl+T on the other hand (or the Navigate To command, however you access it) can find methods by their bare name. This keystroke even works directly from the NativeMethods.txt file. Usually, at least.
We avoid CsWin32 dumping a bunch of types into a namespace populated by other existing assemblies, lest type collisions be introduced. I'll see though what we can do to make the namespace more discoverable (e.g. put it into the README more prominently).
Finding the generated files can be a challenge if you don't already know where to find them. See my response to @ITaluone on how you can find these.
It doesn't need to implement it. Super counter-intuitive I know, but these types are just facades over native objects and COM. This code actually compiles and runs: IKnownFolderManager f = (IKnownFolderManager)new KnownFolderManager(); Call it C#/.NET magic, but the constructor for And ultimately, the reason CsWin32 doesn't generate an interface on the class to make it clear that it would succeed is that in the win32metadata from which code generation runs, the class is just a struct that doesn't implement the interface. And that in turn is because in the win32 header files (I suspect) there is no such interface implemented on the
With CsWin32, the generated code will end up with your own C# code looking a lot like native code. So many of the samples that have been accumulating for decades for C/C++ will actually apply for C#. The win32 api docs themselves will also be immensely helpful to you. It is out of scope (for this repo anyway) to re-document all the APIs or create samples for many of them. But this Discussions tab can become a good place to exchange Q&As with folks on how to use specific APIs as they are generated by CsWin32.
This isn't to say
We have a couple of sometimes opposing goals: We want CsWin32 to generate APIs that are true to the underlying win32 APIs and that require little or no marshaling for maximum performance; but we also want the APIs to be user-friendly. Like the deprecated PInvoke project we may offer more method overloads to make
One caution to add in general: pinvoke.net or stackoverflow code may appear to work for you, but from what I've observed it is often incorrect. It may work well enough on an x64 machine for your use case, but it may fail in x86 or arm64 processes. For example if the native header had a pointer and your C# declaration replaces that with |
Beta Was this translation helpful? Give feedback.
-
I've spent a few hours trying to do a few basic things and I keep stumbling into issues I'd never experienced with pinvoke.net. It seems like a great project - the final pinvoke library to rule them all, but it seriously needs a simple introduction to get people going. I'm sure people who need to use this library for more extensive projects can somewhat quickly get deeply familiar with how things work, but to a plain old C# dev dev like me it feels kinda like stumbling into a bunch of assembly code. :)
Some issues I've been baffled by:
fixed()
or some such. Again, never needed these with pinvoke.net code. Perhaps it did it by itself, perhaps I've been lucky it always worked, but then - it would be helpful to see some examples for how to work with these generated APIs and maybe some explainer on why this is the better way.I may be able to add more later, but please don't take it as plain ranting - I'm just trying to help make this thing better. :) Us C# folk are simple people. I create a new project form a project template in VS and mostly stick to the code editor tabs and the solution explorer. I'll use Stack Overflow or Copilot to find or generate rough outlines of any new API calls I try to use and usually that just works. In this case - I ended up copying most of the code I needed from Windows API Code Pack because the examples of the things I needed used it and it already wraps more of the APIs I needed in a more (WinForms-like) usable manner than a bunch of Win32 C calls wrapped into pinvoke, but I'll still need to add a few more API calls, so I'll try to figure out how to use CsWin32 before I fall back to pinvoke.net. Maybe I'm just not a typical use case for this library that was recommended to me by a colleague... :)
Beta Was this translation helpful? Give feedback.
All reactions