2017-10-31 2 views
6

저에게 적합한 솔루션으로 업데이트되었습니다. 이 질문의 맨 아래를보십시오..NET Core & Xamarin을 사용하여 IL에서 컴파일 된 어셈블리 사용

컨텍스트 :
나는 특정 바이트 크기에 맞도록 배열의 길이를 계산하기위한 제네릭 형식의 크기를 평가하는 방법이 필요했습니다. 기본적으로 sizeof은 C/C++에서 제공하는 것과 유사합니다.

C#의 sizeofMarshal.SizeOf은 많은 제한 사항 때문에 적합하지 않습니다.

이것을 염두에두고 필자는 IL에서 sizeof opcode를 통해 찾고 있던 기능을 사용할 수있는 어셈블리를 작성했습니다. 참조 유형이 본질적으로 IntPtr.Size 인 것으로 알고 있습니다.

.NET 표준 & 코어 용으로 복제했습니다. mscorlib에 해당하는 정확한 내용을 참조하십시오. 일리노이가 잘 컴파일된다는 것에 유의하십시오.이 질문은 다른 문제입니다.

코드 : 대상 프레임 워크 당
헤더 :

.NET : (윈도우 \ Microsoft.NET 프레임 워크 \ \ v4.0.30319 Ilasm.exe를 \)

.assembly extern mscorlib {} 

.NET 표준 : (nuget 추출 ILASM)

.assembly extern netstandard 
{ 
    .publickeytoken = (B7 7A 5C 56 19 34 E0 89) 
    .ver 0:0:0:0 
} 
.assembly extern System.Runtime 
{ 
    .ver 0:0:0:0 
} 

.NET 코어 (표준 동일 ILASM하지만

.assembly Company.IL 
{ 
    .ver 0:0:1:0 
} 
.module Company.IL.dll 

// CORE is a define for mscorlib, netstandard, and System.Runtime 
.class public abstract sealed auto ansi beforefieldinit 
    Company.IL.Embedded extends [CORE]System.Object 
{ 
    .method public hidebysig specialname rtspecialname instance void 
    .ctor() cil managed 
    { 
    .maxstack 8 
    ldarg.0 
    call instance void [CORE]System.Object::.ctor() 
    ret 
    } 

    .method public hidebysig static uint32 
    SizeOf<T>() cil managed 
    { 
    sizeof !!0 
    ret 
    } 
} 

문제 : 나는

.assembly extern System.Runtime 
{ 
    .ver 0:0:0:0 
} 

는 소스)를 모두 테스트 한 이러한 방식으로 컴파일 된 모든 DLL이 .NET 코어 또는 자 마린 응용 프로그램에서 참조
, 내가받는 다음 오류 :

The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.

이러한 DLL은 .NET 프로젝트에서 참조하거나 NET 표준 라이브러리는 .NET 프로젝트에서 참조합니다.

다른 버전과 어셈블리에서이 오류에 대해 자세히 설명한 수많은 기사, 게시물 및 리포지토리를 읽었습니다. 일반적인 솔루션은 대상 프레임 워크의 mscorlib (이동이 용이함)에 해당하는 것에 대한 명시적인 참조를 추가하는 것으로 보입니다. .NET 표준 & 코어 용 IL 컴파일 어셈블리 사용에 대한 정보가 부족한 것 같습니다.

내 이해에 따르면 .NET 표준 & 코어는 대상 형식 프레임 워크의 런타임에 의해 유형 정의가 전달 될 수 있도록 전달 형식을 정의하여 이식성을 가능하게합니다.동일한 참조를 사용하여 C#을에서 컴파일 System.Runtime

  • 분해 .NET의 핵심 라이브러리의

    • 명시 버전 :

      나는 다음을 시도했습니다. 이상하게도 명시 적 버전 (예 : .NET Core 2.0의 System.Runtime 4.2)을 대상으로하는 것으로 보입니다.

    • Emit API을 사용하여 동적으로 코드를 생성합니다. 메모리로 컴파일하는 것은 작동하지만 나도 Xamarin.iOS (AOT 만)를 타겟팅하기 때문에 옵션이 아닙니다. 동적으로 컴파일 된 어셈블리를 디스크에서 참조하면 수동으로 컴파일 한 것과 같은 오류가 발생합니다.

    업데이트 : (빌드 지침 here 다음) Jacek's answer에서 솔루션을 시도, 아직 통해 파고 후, 빌드 스크립트 나 그러나 VS 2017와 corefx를 컴파일 내 시스템을 구성 할 수
    코드 System.Runtime.CompilerServices.Unsafe 해결책을 발견했습니다.

    아마도 이것은 분명해 보이지만 나는 System.Runtime의 잘못된 버전을 참조하고있었습니다. (corefx에서 복사) 대상 프레임 워크 당

    헤더 :

    .NET :

    #define CORELIB "mscorlib" 
    
    .assembly extern CORELIB {} 
    

    .NET 표준 :

    #define CORELIB "System.Runtime" 
    #define netcoreapp 
    
    // Metadata version: v4.0.30319 
    .assembly extern CORELIB 
    { 
        .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A) 
        .ver 4:0:0:0 
    } 
    

    .NET 코어 :

    #define CORELIB "System.Runtime" 
    
    // Metadata version: v4.0.30319 
    .assembly extern CORELIB 
    { 
        .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A) 
        .ver 4:0:0:0 
    } 
    

    모든 소스 파일에서 0123을 사용하십시오. mscorlib의 참조 유형에 대해(예 : [CORELIB]System.Object).

  • +0

    'Reflection.Emit' 시도의 결과는 무엇입니까? – thehennyy

    +0

    @thehennyy 자세한 내용이 업데이트되었습니다. –

    +0

    @ KobyDuck : IL 전용 어셈블리를 참조하는 프로젝트에서 컴파일 오류를 억제하기위한 옵션을 추가했습니다. 이것은 도움이 될 수도 있습니다. –

    답변

    3

    DotNet CoreFX 레포에서 올바르게 수행하는 방법에 대한 좋은 예가 있습니다. System.Runtime.CompilerServices.Unsafe은 IL 전용 어셈블리이며 .NET Core 및 Xamarin에서 사용할 수 있습니다. 문제에 대한 두 가지 접근 방법이있다

    https://github.com/dotnet/corefx/tree/master/src/System.Runtime.CompilerServices.Unsafe

    : - 시간과 매우 관련된 일 무슨 - (내가) 처음부터 프로젝트의 빌드 구성의 필수 요소를 다시 시도 corefx 빌드 시스템은 정말 복잡하다 (ii) 기존 빌드 인프라를 사용하고 System.Runtime.CompilerServices.Unsafe 프로젝트를 복제하고 네이밍을 변경하고 IL 코드를 당신으로 대체하여 .NET 코어 CoreFX 레포에서 IL 프로젝트를 생성하십시오. 내 생각에 이것은 모든 타겟과 올바르게 작동하는 IL 기반 어셈블리를 빌드하는 가장 빠른 방법입니다. .NET 코어 또는 .NET 표준의 특정 버전을 대상으로하면서

    바로 릴리스 지점에서 그것을 만들 어셈블리를 빌드하려면 release/2.0.0, release/1.1.0

    The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.

    는 것을 억제하기위한 시도 할 수있는 옵션이 있습니다 프로젝트를 참조하는 어셈블리 참조에서 컴파일 오류 만 발생했습니다.다음과 같은 속성을 새로운 형식의 csproj/vbproj에 넣으면이를 억제해야합니다 :

    <PropertyGroup> 
        <_HasReferenceToSystemRuntime>true</_HasReferenceToSystemRuntime> 
    </PropertyGroup> 
    
    +0

    나는 정말 바빴고이 일을 시도 할 시간이 없었다. 나중에이 사진을주고 다시 보겠습니다. 감사. –

    +0

    corefx를 컴파일 할 수 없었지만 귀하의 대답은 저에게 해결책이되었습니다. 자세한 내용은 업데이트 된 질문을 참조하십시오. corefx를 컴파일 할 수있는 사람들을위한 솔루션이 필요합니다. –

    관련 문제