知識マップ: C# Native AOT DLLをC/C++から呼び出す方法
記事「C# Native AOT DLLをC/C++から呼び出す方法」の主張を、概念と関係(エッジ)に分解した知識グラフの全体です。各関係には根拠・確認日・確度が付いています。
C#のNative AOTはUnmanagedCallersOnly属性を付けたメソッドをCのエントリポイントとして公開でき、既存のC/C++アプリからin-processでC#のロジックだけを呼び出せる構成を実現する。ただし境界に出せるのはblittableな型に限られるため、実務ではstringやList<T>を直接見せずcreate/destroy/operateのようなハンドルベースのC APIに落とし、呼び出し規約を明示し、例外の代わりにstatus codeでエラーを表現する設計が推奨される。この構成はC/C++がC#ロジックを呼ぶ向きに適する一方、C#からCを呼ぶならP/Invoke、C#からC++を自然に扱うならC++/CLI、32bit/64bitやプロセス境界を越えたい場合やアンロードしたい場合はCOM/IPCの方が向く。ハンドルの採番を32bit幅で使い回すと一周時に無関係なインスタンスを指す危険があり、世代番号の埋め込みが対策になる。
flowchart LR
accTitle: Native AOTでC#をネイティブDLLとしてC/C++から呼ぶ知識マップ
accDescr: Native AOTとUnmanagedCallersOnlyでC#をC/C++から呼ばれるネイティブDLLとして発行できること、境界面をC ABIに落とすための呼び出し規約・blittable型・ハンドル設計・エラー表現の要点、P/Invoke・C++/CLI・COMとの使い分けを示す図
native_aot["Native AOT"]
unmanagedcallersonly["UnmanagedCallersOnly属性"]
blittable_type["blittable型"]
calling_convention["呼び出し規約(calling convention)"]
c_abi["C ABI(Application Binary Interface)"]
native_aot_publish_toolchain["Native AOT publish用のネイティブツールチェーン"]
dotnet[".NET(Core以降)"]
native_to_managed_inprocess_call["C/C++からC#ロジックをin-processで呼ぶ要件"]
p_invoke["P/Invoke"]
csharp_calls_c_functions["C#からCの関数群を呼ぶ要件"]
cpp_cli["C++/CLI"]
csharp_calls_cpp_library["C#からC++ライブラリを自然に扱う要件"]
com_interop["COM(Component Object Model)"]
cross_process_or_bitness_boundary["32bit/64bitまたはプロセス境界を越える要件"]
plugin_unload_requirement["プラグインを後でアンロードしたい要件"]
status_code_error_convention["エラーをstatus codeで返す設計"]
handle_based_api_design["ハンドルベースのC API設計(create/destroy/operate)"]
handle_counter_overflow["ハンドル採番カウンターのオーバーフロー"]
handle_wraparound_collision["ハンドル一周による衝突"]
generation_embedded_handle["世代番号を埋め込んだハンドル設計"]
dumpbin["dumpbin"]
import_library["インポートライブラリ(.lib)"]
native_aot -->|"利用する"| unmanagedcallersonly
unmanagedcallersonly -->|"前提とする"| blittable_type
calling_convention -->|"で構成できる"| unmanagedcallersonly
c_abi -->|"利用する"| calling_convention
unmanagedcallersonly -->|"前提とする"| c_abi
native_aot -->|"前提とする"| native_aot_publish_toolchain
native_aot -->|"前提とする"| dotnet
native_aot -->|"推奨される対応"| native_to_managed_inprocess_call
p_invoke -->|"推奨される対応"| csharp_calls_c_functions
cpp_cli -->|"推奨される対応"| csharp_calls_cpp_library
com_interop -->|"推奨される対応"| cross_process_or_bitness_boundary
native_aot -->|"用いるのは非推奨"| cross_process_or_bitness_boundary
native_aot -->|"用いるのは非推奨"| plugin_unload_requirement
status_code_error_convention -->|"推奨される対応"| unmanagedcallersonly
handle_based_api_design -->|"推奨される対応"| unmanagedcallersonly
handle_counter_overflow -.->|"原因になり得る"| handle_wraparound_collision
generation_embedded_handle -->|"防止する"| handle_wraparound_collision
native_aot -->|"で確認できる"| dumpbin
import_library -.->|"前提とする"| native_aot
native_aot -->|"用いるのは非推奨"| csharp_calls_c_functions
native_aot -->|"用いるのは非推奨"| csharp_calls_cpp_library
handle_based_api_design -.->|"原因になり得る"| handle_wraparound_collision
概念間の関係(全22件)
図と同じ関係を文章でも列挙します。表示している文と機械可読な意味データ(RDFa)は同じ要素に載っています。確度が「確立した関係」のものは直接の関係として、「条件付きの関係」のものは成立条件つきの言明(rdf:Statement)として表現しています。
- Native AOTはUnmanagedCallersOnly属性を利用します。
- UnmanagedCallersOnly属性はblittable型を前提とします。
- 呼び出し規約(calling convention)はUnmanagedCallersOnly属性で構成できます。
- C ABI(Application Binary Interface)は呼び出し規約(calling convention)を利用します。
- UnmanagedCallersOnly属性はC ABI(Application Binary Interface)を前提とします。
- Native AOTはNative AOT publish用のネイティブツールチェーンを前提とします。
- Native AOTは.NET(Core以降)を前提とします。
- Native AOTはC/C++からC#ロジックをin-processで呼ぶ要件に対する本記事の推奨です。
- P/InvokeはC#からCの関数群を呼ぶ要件に対する本記事の推奨です。
- C++/CLIはC#からC++ライブラリを自然に扱う要件に対する本記事の推奨です。
- COM(Component Object Model)は32bit/64bitまたはプロセス境界を越える要件に対する本記事の推奨です。
- Native AOTを32bit/64bitまたはプロセス境界を越える要件に用いることは推奨されません。
- Native AOTをプラグインを後でアンロードしたい要件に用いることは推奨されません。
- エラーをstatus codeで返す設計はUnmanagedCallersOnly属性に対する本記事の推奨です。
- ハンドルベースのC API設計(create/destroy/operate)はUnmanagedCallersOnly属性に対する本記事の推奨です。
- ハンドル採番カウンターのオーバーフローはハンドル一周による衝突の原因になることがあります。
- 世代番号を埋め込んだハンドル設計はハンドル一周による衝突を防ぎます。
- Native AOTはdumpbinで確認できます。
- インポートライブラリ(.lib)はNative AOTを前提とします。
- Native AOTをC#からCの関数群を呼ぶ要件に用いることは推奨されません。
- Native AOTをC#からC++ライブラリを自然に扱う要件に用いることは推奨されません。
- ハンドルベースのC API設計(create/destroy/operate)はハンドル一周による衝突の原因になることがあります。
主要概念の定義
機械可読データ
このページはサイトの知識グラフ(_data/knowledge/)から自動生成されています。誤りの指摘はお問い合わせからお願いします。