Comments (13)
This is the tool I am talking about: https://github.com/sharpdx/SharpDX/tree/master/Source/Tools/SharpGen
Notice how it also has a CPP parser etc.
from pinvoke.
Thanks for the idea. Anything we can do to expedite increasing our API coverage with less effort is worth investigating.
FWIW, I've already been using pinvoke.net and the code generation feature of the P/Invoke Interop Assistant as a tool to help generate the signatures and struct types. I've been disappointed by the code generation of that tool though, as the method is may not be in the database, or it fails to parse the header files and produces nothing, or it produces a bunch of signatures that have to be fixed up simply because the header file used PUCHAR
instead of void*
resulting in byte*
in the managed code when it should have been void*
or IntPtr
. So I usually just write out the signature myself, but refer to pinvoke.net or the tool output to see if it can save me time along the way.
Ultimately the very best generation tool in the world would still emit methods that would need to be hand-inspected, IntPtr
replaced with SafeHandle
where appropriate, helper methods added in a few cases, xml doc comments added, etc.
Hopefully SharpGen does a better job. But even if it did, I'm not sure we'd use it to replace the process of maintaining source code for the library with simply generating the source code at build time. Not sure if that was what you were suggesting. If you (or anyone else) can try out SharpGen
and let us know how useful it is for some methods you want to contribute, I'm sure folks would find it interesting -- especially if your report is positive.
from pinvoke.
As for SafeHandle
vs IntPtr
, can't we use SafeHandle
in all cases? It uses an IntPtr
internally anyway.
I was considering writing a plugin which takes P/Invoke Interop Assistant's output, parsing it with Roslyn, and then using Roslyn, re-transpiling it into something we want (with fixes and tweaks).
from pinvoke.
As for SafeHandle vs IntPtr, can't we use SafeHandle in all cases?
No. SafeHandle is supposed to represent native handles -- things that some sort of native release method must be called on. IntPtr can represent many things, including just a pointer-sized number (like the size of a buffer). Other times when they do represent handles, such as for structs that are initialized by the native code, the fields can't be SafeHandles because .NET can't marshal that way.
Massaging the output of a code generation tool sounds interesting. This is to aid us in checking in source code, I assume? Or is it to replace our source code? I'd be much more quick to adopt the former (as a tool to help us author source code) than the latter (a replacement for source code).
from pinvoke.
I think it is worth investing in Roslyn to see if it can replace our code. If not, it can always aid us. I am quite experienced in Roslyn, and think I can make a program that can very easily generate automatic code that follows exactly the same structure as we use now.
But what to do about SafeHandle
vs IntPtr
? Is there any way we can see the difference between the two? Let's think out of the box and think over-engineering, just for the sake of brainstorming. Could we use a Selenium parser on the MSDN article of the given PInvoke call and see it there?
from pinvoke.
I don't think that a generated solution would be a good one in the long run. Lot of API require thinking on how to adapt them to good C#.
The only thing something automated would be able to produce is bad C# :
IntPtr
versusSafeHandle
is a problem,SIZE_T
is anIntPtr
and have no sense as aSafeHandle
.- There isn't one
SafeHandle
but many, one per resource type. - Enums are problematic, parsing C would in a lot of case produce just a bunch of const as they might not exists in the C code, and parsing documentation risk producing too much enums in cases where functions allow only a subset of values from a common enum.
void*
is the correct marshaling for buffers to allow all usages but in some casesbyte[]
is good enough for most use-cases.string
orStringBuilder
depends on usage- Cases where the
NullableUIntPtr
type or similar is needed are hard to guess and using it everywhere will make the API hard to read. In most casesref uint
orout uint
is good enough. - Documentation need to be adapted to document correctly the API, not just copy the native API.
And that's only the case I can think of that poped from the API already in there, i'm sure we will encounter a LOT more.
That said a selenium based tool to generate at least a good baseline from the MSDN page would be extremely handy. Especially around documentation, cleaning it up by hand is ok but the copy-paste from MSDN part is just boring mechanical work.
from pinvoke.
Alright, let me try to gather more intel then given the above information (thanks by the way).
- As for
IntPtr
versusSafeHandle
in the case ofSIZE_T
, we just make it have allSIZE_T
items converted intoIntPtr
instead. - What do you mean regarding "many
SafeHandle
, one per resource type"? - Yes, enums could be a problem. However, they are all typically prefixed by something common (for instance,
WM_
for window message constants likeWM_MOUSEMOVE
). This could be used to our advantage, and to generate enums (or constants) in a smarter way. - As for
void*
versusbyte[]
, why not just have both? I think all this talk about performance issues is premature optimization. If one thing is preferred over the other in most cases anyway, we could even have that as the default (for instance, having aMyPInvokeCall
andMyPInvokeCallVoid
or whatever). - Why the need for adapting the documentation to the API? Why can't it be copied from MSDN?
Thanks for your clarification so far.
from pinvoke.
What do you mean regarding "many SafeHandle, one per resource type"?
The same native library can contain lots of functions that take a HANDLE
, some of theses are to be closed by CloseHandle
, other FreeLibrary
, and a few others. Any tool automating that would need to contain that hardcoded as it's not always obvious from the documentation (Often it' references handles created by function Foo, and it's the documentation of function Foo that explain how to free the resource).
Yes, enums could be a problem. However, they are all typically prefixed by something common
Some are, some aren't completely depends on the API, we would have lots of special cases that can't be generated, and the more special casing the less useful an automated too would be.
As for void* versus byte[], why not just have both?
It's possible but it might polute the API surface with lots of variants that have no chance to ever be used.
Why the need for adapting the documentation to the API? Why can't it be copied from MSDN?
Documentation sometimes link to generic articles on MSDN, references constants values one by one (where we would use enums and so just reference it), specifies what happens when some values are null that we marshalled as ref
or out
(And so can't be null)
There are a few changes like that that make the doc easier to consume for libraries users. (Nothing really critical but it's nice to have the library go the extra mile and provide adapted documentation that take the marshaling in account)
from pinvoke.
Hmmm, I think we can close this then. Damn! Really wanted it to work somehow, but I get your points.
from pinvoke.
I may have missed part of the conversation somewhere. Which points condemned this idea?
from pinvoke.
Oh, nm. I got my issues confused.
from pinvoke.
I'm pleased to say we have a very good option opening up to automatically generate All The Things.
Reactivating to track.
from pinvoke.
This is now closed by #565.
from pinvoke.
Related Issues (20)
- Request: Better exception handling or documentation for CreateFile HOT 3
- Refresh packages on NuGet HOT 1
- Change NTSTATUS/HResult FACILITY_CODE to match CsWin32 definitions HOT 3
- No release / release notes for 0.7.124 HOT 1
- User32.InvalidateRect missing
- Refactor FacilityCode bitshift op to Facility properties
- MCG0037 error release build with Kernel32 HOT 3
- Support for .NET 6 to include in Maui? HOT 2
- User32+MOUSEINPUT.cs has the wrong type for mouseData
- `User32.EnumChildWindows` has wrong typed argument HOT 1
- Dwmapi DwmIsCompositionEnabled is missing HOT 1
- Init script exception calling "DownloadFile" 404 Not Found HOT 5
- Kernel32.QueryFullProcessImageName broken on Windows 7 HOT 2
- Type of DLGTEMPLATE HOT 1
- User32.SetLayeredWindowAttributes missing HOT 2
- DirectX Video Acceleration HOT 1
- Missing user32 DeleteMenu HOT 5
- Missing user32 RegisterHotKey HOT 2
- Add mpr.dll HOT 1
- Add support for mssign32.dll HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pinvoke.