get 메서드로 간단한 인터페이스 속성을 명시 적으로 구현하는 클래스를 내 보냅니다. 이식 가능한 클래스 라이브러리에 인터페이스가 정의되어 있지 않으면 문제가 없습니다. 그러나 인터페이스를 PCL로 이동하고 IEnumerable<int>
, PEVerify 와 같은 특정 유형 만 사용 하면 PEVerify가 실패합니다.
보면 ILDASM -> 메타 정보는 ->보기 , 당신은 둘 것을 볼 것입니다 mscorlib
및 System.Runtime
조립 참조를 가져옵니다. 이것은 DefineMethodOverride
(볼 수 AssemblyBuilder.GetReferencedAssemblies()
있도록)에 전화하는 동안 발생합니다 . IEnumerable`1이 두 어셈블리 모두에서 TypeRef로 가져온 것을 볼 수 있는데, 이는 문제인 것 같습니다.
인터페이스를 PCL로 분리하지 않거나 유형을 다른 것으로 변경하면 작동하며 System.Runtime
참조는 포함되지 않습니다. 시도하려면 string
교체 IEnumerable<int>
와 string
인터페이스뿐만 아니라에서 DefineProperty
/ DefineMethod
전화.
이 문제를 재현하는 간단한 방법으로 MSDN 의 수정 된 예제 를 사용하여 콘솔 프로젝트에 아래 코드를 드롭하면 모든 것이 잘 작동합니다. interface I
이식 가능한 클래스 라이브러리 프로젝트로 이동 하면 내가 의미하는 바를 정확히 알 수 있습니다.
PEVerify 오류를 어떻게 제거 할 수 있습니까?
오류 : MethodImpl의 Decl (token = 0x0a000001) 및 Body (token = 0x00610072) 메서드 서명이 일치하지 않습니다. [토큰 : 0x19000001] [시간 : 0x801312F4]
public interface I
{
IEnumerable<int> E { get; }
}
class Test
{
static void Main()
{
string name = "DefineMethodOverrideExample";
AssemblyName asmName = new AssemblyName(name);
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule(name, name + ".dll");
TypeBuilder tb = mb.DefineType("C", TypeAttributes.Public);
tb.AddInterfaceImplementation(typeof(I));
PropertyBuilder prop = tb.DefineProperty("I.E", PropertyAttributes.None, typeof(IEnumerable<int>), Type.EmptyTypes);
MethodBuilder mbIM = tb.DefineMethod(
"I.get_E",
MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName,
typeof(IEnumerable<int>),
Type.EmptyTypes);
prop.SetGetMethod(mbIM);
ILGenerator il = mbIM.GetILGenerator();
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ret);
tb.DefineMethodOverride(mbIM, typeof(I).GetProperty("E").GetGetMethod());
Type tc = tb.CreateType();
ab.Save(name + ".dll");
}
}
(.Net 4.5.1)
(C : \ Program Files (x86) \ Microsoft SDKs \ Windows \ v8.1A \ bin \ NETFX 4.5.1 Tools \ x64의 PEVerify 및 ILDASM 버전 4.0.30319.33440)
감사!
내보내고 컴파일 된 예제와 좀 더 비교하고 .NET 라이브러리 를 파헤친 후 ModuleBuilder.DefineMethodOverrideNoLock
-> GetMethodTokenInternalNoLock
(인터페이스에서) 에 대한 호출에서 주요 차이점을 발견 할 수있었습니다. 제공은 MethodInfo
A는 RuntimeMethodInfo
. 궁극적으로를 호출 GetMemberRefOfMethodInfo
하면을 포함 System.Runtime
하여 IEnumerable
.
비공개 멤버에 반영 할 필요가없는 방식으로이 문제를 해결하려면 MethodInfo
모든 메서드를 재정의 하는 상속 되는 프록시 또는 래퍼를 만들어 원본 RuntimeMethodInfo
. 이렇게하면 ILDASM이 PCL 인터페이스 메서드를 명시 적으로 구현하려는 컴파일 된 (비 방출) 어셈블리에 나타나는 TypeRef 및 TypeSpec 요소를 표시합니다. 이 기술을 사용하여 방출 된 어셈블리를 성공적으로 확인할 수있었습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다