私に適したソリューションで更新されました。この質問の下部を見てください。.NET Core&Xamarinを使用してILからコンパイルされたアセンブリを使用する
コンテキスト:
私は特定のバイトサイズ内に収まるように、配列の長さを計算する目的のための一般的な種類の大きさを評価する方法が必要でした。基本的には、 sizeof
とC/C++の類似点があります。
C#のsizeof
およびMarshal.SizeOfは、多くの制限があるため、これには適していません。
これを念頭に置いて、私はsizeof
オペコードで探していた機能を可能にするILにアセンブリを書きました。私はそれが本質的に参照型でIntPtr.Size
と評価されていることを知っています。
私はこれを.NET標準&コアに複製しました。これはmscorlibの正しい同等品であると信じていました。 ILがうまくコンパイルすることに注意してください。この問題は別の問題です。
コード:ターゲットフレームワークあたり
ヘッダ:
.NET:(Windowsの\ Microsoft.NET Frameworkの\ \ 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、しかしこのようにコンパイルされたDLLは、.NET CoreまたはXamarinアプリケーションによって参照されている場合は、私が受け取る、
:
.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
}
ソースをテストしてみました次のエラーが発生しました:
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 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
)。
あなたの 'Reflection.Emit'試行の結果はどうでしたか? – thehennyy
@thehennyy詳細については更新されました。 –
@ KobyDuck:ILのみのアセンブリを参照するプロジェクトでコンパイルエラーを抑制するオプションを追加しました。これも同様に役立つかもしれません。 –