Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone show me an example of MethodImplOptions.ForwardRef

It looks cool on MSDN:

Specifies that the method is declared, but its implementation is provided elsewhere.

So I tried it in a console application:

public class Program
{
    [MethodImplAttribute(MethodImplOptions.ForwardRef)]
    public static extern void Invoke();

    static void Main(string[] args)
    {
        Invoke();
        Console.Read();
    }
}

Then what should I do now? Where can I provide the implementation of Program.Invoke?

like image 687
Cheng Chen Avatar asked Jul 26 '11 06:07

Cheng Chen


2 Answers

The usage of ForwardRef goes pretty much like this:

consumer.cs

using System;
using System.Runtime.CompilerServices;

class Foo
{
    [MethodImplAttribute(MethodImplOptions.ForwardRef)]
    static extern void Frob();

    static void Main()
    {
        Frob();
    }
}

provider.cs

using System;
using System.Runtime.CompilerServices;

class Foo
{
    // Need to declare extern constructor because C# would inject one and break things.
    [MethodImplAttribute(MethodImplOptions.ForwardRef)]
    public extern Foo();

    [MethodImplAttribute(MethodImplOptions.ForwardRef)]
    static extern void Main();

    static void Frob()
    {
        Console.WriteLine("Hello!");
    }
}

Now the magic sauce. Open a Visual Studio command prompt and type:

csc /target:module provider.cs
csc /target:module consumer.cs
link provider.netmodule consumer.netmodule /entry:Foo.Main /subsystem:console /ltcg

This uses one of the lesser known functionality of the linker where we're linking managed modules together. The linker is able to gel together same-shaped types (they need to have the exact same methods, etc.). ForwardRef is the thing that actually lets you provide implementation elsewhere.

This example is kind of pointless, but you can imagine things getting more interesting if a single method is implemented in a different language (e.g. IL).

like image 104
Michal Strehovský Avatar answered Nov 11 '22 02:11

Michal Strehovský


My understanding is that ForwardRef acts in the same way as extern, and is intended for guiding the runtime when the language you are using lacks direct support (via extern in C#). As such, the usage should be very similar to the extern modifier, most notably using [DllImport(...)].

like image 34
Marc Gravell Avatar answered Nov 11 '22 04:11

Marc Gravell