Search code examples
c#.netvb.netpinvoke

Best practices for organizing .NET P/Invoke code to Win32 APIs


I am refactoring a large and complicated code base in .NET that makes heavy use of P/Invoke to Win32 APIs. The structure of the project is not the greatest and I am finding DllImport statements all over the place, very often duplicated for the same function, and also declared in a variety of ways:

The import directives and methods are sometimes declared as public, sometimes private, sometimes as static and sometimes as instance methods. My worry is that refactoring may have unintended consequences but this might be unavoidable.

Are there documented best practices I can follow that can help me out?

My instict is to organize a static/shared Win32 P/Invoke API class that lists all of these methods and associated constants in one file... EDIT There are over 70 imports to the user32 DLL.

(The code base is made up of over 20 projects with a lot of windows message passing and cross-thread calls. It's also a VB.NET project upgraded from VB6 if that makes a difference.)


Solution

  • You might consider the way it was done in the .NET framework. It invariably declares a static class (Module in VB.NET) named NativeMethods that contains the P/Invoke declarations. You could be more organized than the Microsoft programmers, there are many duplicate declarations. Different teams working on different parts of the framework.

    However, if you want to share this among all projects you have to declare these declarations Public instead of Friend. Which isn't great, it ought to be an implementation detail. I think you can solve that by re-using the source code file in every project that needs it. Normally taboo but okay in this case, I think.

    I personally declare them as needed in the source code file that needs them, making them Private. That also really helps when lying about the argument types, especially for SendMessage.