2015-02-19 8 views
1

Я не уверен, что я делаю неправильно здесь. Я создаю dll, который использует код в моей текущей сборке. Вот упрощенная версия, содержащая только код, вызывающий эту проблему.peverify: Метод не виден?

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 

Что означает эта ошибка? и что я делаю неправильно?

Спасибо!

EDIT:

Вот что сгенерированный метод выглядит в 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 
+0

Является ли сборка вы генерируете этот код из доступных для PEVerify, когда вы его запускаете? То есть, это «CustomSerializer.dll/exe» в том же каталоге или GAC? –

+0

@JeroenMostert CustomSerializer.exe и SerTest.dll находятся в одном каталоге yes. – vexe

+0

Также, только что проверил код C# в ILSpy, он не выдавал никаких ошибок при просмотре класса (иногда это делает, если код был недействителен) и отображал правильный код: «int typeId = Swift.GetTypeId (obj);» – vexe

ответ

2

«Метод не виден» означает метод ссылки не видно сборки вызывающего его. Если вы не используете InternalsVisibleTo (какой PEVerify, похоже, не понимает, кстати) или protected internal, это означает: метод должен быть общедоступным методом видимого класса, а видимый класс является открытым классом, необязательно вложенным в видимый класс. Если вам не нравится это рекурсивное определение: это public полностью down up.

Код как опубликованный должен работать (Swift является не вложенным публичным классом и GetTypeId общедоступным методом), поэтому проблема заключается в том, что код не опубликован.