Skip to content
GeirGrusom edited this page Apr 7, 2014 · 5 revisions

Platform.Invoke

Add the ability to substitute and add logging to your platform calls! Using Reflection.Emit this library can create an implementation of a P/Invoke interface using a specified function source.

Using Platform.Invoke

There are several ways to use the library depending on your requirments. For most applications, you can probably just go down the attribute road

The Attribute Road

There are a few attributes defined:

  • Library - This declares the library to bind the interface against. Applies to interfaces and abstract classes. Required by Implementation class. Optional for LibraryInterfaceFactory.
  • EntryPoint - Defines the entry point used by the method. Applies to methods in an interface or abstract class. Optional.
  • EntryPointFormat - Allows you to easily define a common entrypoint naming convention. Applies to interfaces and abstract classes. Optional.
  • SkipProbeAttribute - Specifies that any probe interface is not invoked on this method. Optional.

Note the preferred sequence for the implementation:

  1. Implementation override definition
  2. Attributes
  3. Interface definition

In other words it will prefer arguments in the Implement overloads over attributes, and attributes over interface definition information.

###Example###

[Library("gdi32")]
IMessageBoxApi
{
    int MessageBox(IntPtr hWnd, string text, string title, int style);
}

If you want to rename the method:

[Library("gdi32")]
IMessageBoxApi
{
    [EntryPoint("MessageBox")]
    int MsgBox(IntPtr hWnd, string text, string title, int style);
}

Now that hyou have your definition, you can get an instance of it by using the Implementation class. Note that this class caches the results.

var msg = Implementation<IMessageBoxAPI>.Instance;
msg.MessageBox(IntPtr.Zero, "Hello World!", "Message from Hello World Application", 1);

You can of course replace the "int style" with the enumeration specified in the documentation.

Note: The attribute way of doing things does not presently support function call probing.

The imperative road

You can also do things a little more manually by using the LibraryInterfaceFactory class. It gives you a lot more control. For example you can provide your own ILibrary implementation which allows you to get your functions from somewhere else, such as *glGetProcAddress.

You declare the interface the same way as the attribute way (they all still apply, but you can override the behavior) but all of the attributes are now optional depending on which overload you chose.

I will just show the most manual-est way of getting an interface to underline the gist of how the library actually works, but there are several overloads available, so check them out.

###Example###

var libraryLoader = LibraryLoaderFactory.Create();
var library = libraryLoader.Load("user32");
var probe = new ProcProbe((m, i) => Console.WriteLine("starting {0}...", m.Name), (m, i) => Console.WriteLine("ended {0}!", m.Name));
var msgBox = LibraryInterfaceFactory.Implement<IMessageBox>(library, probe);
msg.MessageBox(IntPtr.Zero, "Hello World!", "Message from Hello World Application", 1);

You can also supply your own method wrappers as well, but this is somewhat more complicated. Check the source code for more information on this.

Clone this wiki locally