【问题标题】:peverify: Method is not visible?peverify:方法不可见?
【发布时间】:2015-02-19 12:28:24
【问题描述】:

我不确定我在这里做错了什么。我正在生成一个使用当前程序集中代码的 dll。这是一个简化版本,仅包含导致问题的代码。

static void Main()
{
    Swift.Init();
}

public static class Swift
{
    public static int GetTypeId(object obj)
    {
            return 0;
    }

    public static void Init()
    {
            var getTypeIdMethod = typeof(Swift).GetMethod("GetTypeId",
                BindingFlags.Public | BindingFlags.Static);

            var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Asm"), AssemblyBuilderAccess.RunAndSave);
            var modBuilder = asmBuilder.DefineDynamicModule("Mod", "SerTest.dll");
            var typeBuilder = modBuilder.DefineType("TEST", TypeAttributes.Public);
            var methodBuilder = typeBuilder.DefineMethod("SWITCH",
                MethodAttributes.Public | MethodAttributes.Static,
                CallingConventions.Standard,
                typeof(void), new Type[] { typeof(Stream), typeof(object) });

            // arg0: Stream, arg1: object
            var il = methodBuilder.GetILGenerator();
            il.DeclareLocal(typeof(int));

            // load and store id
            il.Emit(OpCodes.Ldarg_1);                   // push object
            il.Emit(OpCodes.Call, getTypeIdMethod);     // pop object, pass to GetTypeId, push id
            il.Emit(OpCodes.Stloc_0);                   // pop, store in local
            il.Emit(OpCodes.Ret);

            typeBuilder.CreateType();
            asmBuilder.Save("SerTest.dll");
    }
}

peverify 给出:

[IL]: Error: [C:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\CustomSerializer\bin\Release\SerTest.dll : TEST::SWITCH][offset 0x00000001] Method is not visible.
1 Error(s) Verifying SerTest.dll

这个错误是什么意思?以及我做错了什么?

谢谢!

编辑:

下面是生成的方法在 ildasm 中的样子:

.method public static void  SWITCH(class [mscorlib]System.IO.Stream A_0,
                                   object A_1) cil managed
{
  // Code size       8 (0x8)
  .maxstack  1
  .locals init (int32 V_0)
  IL_0000:  ldarg.1
  IL_0001:  call       int32 [CustomSerializer]Serializer.Swift::GetTypeId(object)
  IL_0006:  stloc.0
  IL_0007:  ret
} // end of method TEST::SWITCH

【问题讨论】:

  • 当您运行它时,您生成此代码的程序集是否可供 PEVerify 访问?即是同目录下的“CustomSerializer.dll/exe”还是GAC?
  • @JeroenMostert CustomSerializer.exe 和 SerTest.dll 在同一目录中是的。
  • 另外,刚刚检查了 ILSpy 中的 C# 代码,在查看类时它没有抛出任何错误(有时如果代码无效,它会抛出任何错误)并显示正确的代码:“int typeId = Swift .GetTypeId(obj);"
  • 我可以重现此错误的唯一方法是方法 Swift.GetTypeId 确实不是公共的(例如,因为 Swift 嵌套在非公共类型中)。但在您发布的 IL 中似乎并非如此。
  • 傻我!我可以发誓我检查了它以确保该方法是公开的。如果需要,请转换为答案。

标签: c# il peverify


【解决方案1】:

“方法不可见”表示引用的方法对调用它的程序集不可见。如果您没有使用InternalsVisibleTo(顺便说一下,PEVerify 似乎无法理解)或protected internal,这意味着:该方法必须是可见类的公共方法,并且可见类是公共的类可选地嵌套在可见类中。如果您不喜欢这种递归定义:它是public 一直向下向上。

发布的代码应该可以工作(Swift 是非嵌套的公共类,GetTypeId 是公共方法),所以问题出在未发布的代码中。

【讨论】:

    猜你喜欢
    • 2014-12-09
    • 1970-01-01
    • 2021-06-26
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    相关资源
    最近更新 更多