2014-02-20 3 views
8

System.Reflection.Emit API를 사용하여 디스크상의 .NET 어셈블리를 생성하는 컴파일러를 작성하고 있습니다. 컴파일러 자체는 .NET 4.5에 대해 작성되지만 생성 된 코드는 휴대용 클래스 라이브러리의 유형 만 참조합니다. 그러나 Windows Phone 8 프로젝트에서 생성 된 어셈블리를 참조하려고 할 때 Visual Studio에서는 A reference to a higher version or incompatible assembly cannot be added to the project이라는 문구를 사용합니다.Reflection.Emit을 통한 휴대용 클래스 라이브러리 생성

디 컴파일러에서 생성 된 어셈블리를 열면 두 개의 PCL과 mscorlib 4.0.0.0을 참조하는 반면, PCL은 mscorlib 2.0.5.0을 참조하는 것으로 간주됩니다.

System.Reflection.Emit API가 PCL을 생성하도록 만들 수 있나요, 아니면 Mono.Cecil으로 마이그레이션 할 수있는 유일한 방법입니까?

+0

IKVM.Reflection을 살펴보고 현재 프레임 워크와 다른 버전의 프레임 워크를 타겟팅 할 수도 있습니다. – svick

+0

@svick 감사합니다. IKVM에 공개 Emit API가 있다는 것을 알지 못했습니다. 언뜻보기에 Mono.Cecil이 더 잘 설계된 것처럼 보입니다. IKVM.Reflection을 선호해야하는 이유가 있습니까? – Trillian

+0

IKVM 반사 API는 의도적으로 일반 반사와 매우 유사합니다.그래서, 이미 알고 있다면, 당신은 매우 빨리 그것을 사용할 수 있어야합니다. – svick

답변

4

좋아요, 내 자신의 질문에 답변 해 드리겠습니다.

System.Reflection.Emit API가 현재 프로세스에서 사용하는 것보다 mscorlib의 다른 버전을 참조하는 어셈블리를 생성 할 수 있다는 증거는 발견하지 못했습니다. 사실 System.Type 매개 변수 및 기타 반사 객체를 사용하는 API는 사용중인 mscorlib 버전에 해당하는 Type.Assembly 속성을 쿼리 한 결과에 대한 참조를 추가 할 수 있습니다.

그러나 휴대용 클래스 라이브러리는 System.Reflection.Emit이 생성하는 것과 다르지 않으므로 조립품을 "휴대용으로 만들 수있는"후에 패치 할 수 있습니다. 면책 조항 :이은 PE 파일 형식에 익숙해야하고 예기치 못한 부작용이있을 수 있습니다,하지만 나를 위해 작동 : 어셈블리를 생성 할 때

  • , 어셈블리에이 속성을 추가 할 수 AssemblyBuilder.SetCustomAttribute를 사용

    이 스케치 얻는 곳
    [System.Runtime.Versioning.TargetFrameworkAttribute(".NETPortable,Version=v4.0,Profile=Profile136", FrameworkDisplayName = ".NET Portable Subset")] 
    
  • 입니다 : 생성 된 어셈블리에 대한 읽기/쓰기 파일 스트림을 열고 AssemblyBuilder.Save라고 한 후 AssemblyRef 테이블 행을 찾습니다 PE, COFF, COM, CLI 및 메타 데이터 테이블 헤더를 통해 걸어 0에 대한. 참조 된 버전 mscorlib2.0.5.0으로 수정하고 0x100을 플래그 ("대상 변경 가능")에 추가하고 공개 키 토큰 blob을 0x7CEC85D7BEA7798E으로 업데이트하십시오.

다른 프레임 워크 어셈블리를 사용하는 경우 참조를 패치해야 할 수도 있습니다 (테스트하지 않았습니다). 그렇지 않으면, voilà! 이제이 어셈블리는 이식성이 있으며 예를 들어 Windows Phone 프로젝트에서 사용할 수 있습니다.

(... 아니면 그냥 Mono.Cecil/IKVM.Reflection ... 사용)

편집을 : 내가 사용하는 코드는 on github를 찾을 수 있습니다. 이는 엄청난 해킹이므로 일반적인 면책 조항이 적용되므로 사용자 자신의 위험을 감수해야합니다.

+0

어셈블리를 수정하는 코드를 작성한 것처럼 보이므로 공유하는 것이 좋습니다. – svick

+0

@svick 나는 하겠지만, 좋은 300+ 라인과 구조체와 enum을 많이 포함하고있다. 나는 그것을 기꺼이 누군가에게 나누어 주겠지 만 ... stackoverflow에 PM과 같은 것이 있다면. – Trillian

+1

pastebin에 게시 할 수 있습니다. – zneak