Home > Software design >  How do you get DllImportAttribute using System.Reflection?
How do you get DllImportAttribute using System.Reflection?

Time:07-13

How do you get info about a DllImport attribute?

I'm using monodevelop inspector to inspect a c# dll that wraps native dll

using System.Runtime.InteropServices;
namespace MonoMac.foo
{
 public class fooFramework
 {
  [DllImport ("/System/Library/Frameworks/foo")]
  public static extern void NSfoo ();
 }
}

I try to "replicate" the inspector functionality in my code using System.Reflection. I got no problem to get a MethodInfo on the NSfoo method. How do you get those (noncustom) attributes? I think

mymethodInfo.Attributes & MethodAttributes.PinvokeImpl

will tell me if the method consists in a extern call. But how can I get more information such as the path to the native dll?

EDIT:
I was using Attribute.GetCustomAttributes(mymethodInfo) or mymethodInfo.GetCustomAttributes(). For some reason, the returned list does not contain any attribute of type DllImport.

Asking explicitly for a DllImportAttribute is the way to go : var dllImport =(DllImportAttribute)mymethodInfo.GetCustomAttribute(typeof(DllImportAttribute)).
If attribute is not null, the "path" is in the property named Value.

CodePudding user response:

Since extern is always static you need to find all static methods and filter them by result of GetCustomAttribute() method:

public class fooFramework
{
    [DllImport ("/System/Library/Frameworks/foo")]
    public static extern void NSfoo ();
}
...
public class MethodData
{
    public MethodInfo MethodInfo { get; set; }

    public DllImportAttribute Attribute { get; set; }

    public string DllPath => Attribute.Value;
}
...
public static List<MethodData> GetDllImportMethods(Type classType)
{
    var methods = classType.GetMethods(BindingFlags.Public | BindingFlags.Static);
    var result = new List<MethodData>();
    foreach (var methodInfo in methods)
    {
        var dllImportAttribute =
            methodInfo.GetCustomAttribute(typeof(DllImportAttribute));
        if (dllImportAttribute == null)
            continue;
        result.Add(new MethodData()
        {
            MethodInfo = methodInfo,
            Attribute = (DllImportAttribute)dllImportAttribute
        });
    }

    return result;
}
...
//Usage:
var methods = GetDllImportMethods(typeof(fooFramework));
Console.WriteLine(methods[0].DllPath); // /System/Library/Frameworks/foo
  • Related