📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
細 文字列「__FORCETOC__」を「{{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This pag… |
|||
| (同じ利用者による、間の10版が非表示) | |||
| 1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
C++ | C++からC#ライブラリの関数を呼び出す方法は、複数の方法が存在しており、各々にメリットおよびデメリットがある。<br> | ||
下表に代表的な5種類の方法を示す。<br><br> | |||
<center> | <center> | ||
{| class="wikitable" | style="background-color:#fefefe;" | {| class="wikitable" | style="background-color:#fefefe;" | ||
|+ C++からC#ライブラリのメソッドを呼ぶ方法 | |||
|- | |- | ||
! style="background-color:#66CCFF;" | 方法 | ! style="background-color:#66CCFF;" | 方法 | ||
| 10行目: | 10行目: | ||
! style="background-color:#66CCFF;" | デメリット | ! style="background-color:#66CCFF;" | デメリット | ||
|- | |- | ||
| C++/ | | C++のプロジェクトをC++/CLIに設定する || C++のプロジェクトの設定において、[CLIを使う]に変更する。<br>VisualStudioのIntelliSenseも使用可能。 || C++/CLIに関するドキュメントが少ない。<br><br><u>Windowsのみ使用可能。</u> | ||
|- | |- | ||
| .NET | | [https://github.com/3F/DllExport .NET DLLExport]を使用して、<br>C#ライブラリのメソッドをエクスポートする || C++/CLIを使用する必要がない。<br><br><code>GetProcAddress</code>関数が使用できるため、<br>よく知られた方法で関数を呼び出す事が出来る || C#ライブラリのソースコードが無い場合は利用できない。<br><br><u>Windowsのみ使用可能。</u> | ||
|- | |- | ||
| C# | | C++からC#ライブラリを呼ぶための<br>C++/CLIのラッパーライブラリを開発する || COMを使用しなくてよい。<br>C++およびC#のプロジェクトの設定を変更しなくてよい。 || C#ライブラリ、および、C++/CLIライブラリの2つのライブラリを作成する必要がある。<br>C++/CLIに関するドキュメントが少ない。<br><br><u>Windowsのみ使用可能。</u> | ||
|- | |- | ||
| | | Embedded Monoを使用する || C++およびC#ライブラリの2つのプロジェクトを作成するだけでよい。<br><u>Linux、MacOSでも使用可能である。</u><br><br><u>ただし、Linux上で使用する場合、</u><br><u><code>async, await</code>や他の様々なシンタックスが使用できない等の</u><br><u>デメリットも多い。</u><br><br>C++のプロジェクトにおいて、<br>Monoに関連するヘッダファイルをインクルードして、C#ライブラリを呼ぶ。<br> || Linuxの場合は、.NET Standard (.NET Core / .NET 5以降ではない) またはMonoを使用して、<br>C#ライブラリを作成する必要がある。<br><br>Windowsの場合は、.NET FrameworkまたはMonoを使用して、C#ライブラリを作成する必要がある。<br><br>したがって、.NET Core / .NET 5以降は使用することができない。<br><br>また、実行環境にもMonoをインストールする必要がある。 | ||
|- | |- | ||
| C# | | C#ライブラリをCOM参照可能にする || C++/CLIライブラリは不要である。 || C++のソースコード量が増えて設計が煩雑となる。<br><br>COM (Component Object Model) は、Windows独自の技術であり、<br><u>Linuxでは直接サポートされていないため、Windowsのみ使用可能である。</u><br><br>COMはWindowsのオブジェクト指向プログラミングモデルであり、<br>Microsoftの開発環境やWindows APIと密接に関連している。 | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
上表1において、以下の手順を記載する。<br> | 上表1において、以下の手順を記載する。<br> | ||
* C++/ | * C++のプロジェクトをC++/CLIに設定する | ||
* | * [https://github.com/3F/DllExport .NET DLLExport]を使用して、C#ライブラリのメソッドをエクスポートする | ||
* C++/ | * C++/CLIのラッパーライブラリを開発する | ||
* C# | * Embedded Monoを使用する | ||
* C#ライブラリをCOM参照可能にする | |||
<br><br> | <br><br> | ||
| 446行目: | 447行目: | ||
MonoString *excString = mono_object_to_string(excObject, nullptr); | MonoString *excString = mono_object_to_string(excObject, nullptr); | ||
const char *excCString = mono_string_to_utf8(excString); | const char *excCString = mono_string_to_utf8(excString); | ||
std::cout << "メソッドの実行時における例外 : " << | std::cout << "メソッドの実行時における例外 : " << excCString << std::endl; | ||
mono_jit_cleanup(domain); | mono_jit_cleanup(domain); | ||
| 532行目: | 533行目: | ||
// メモリの解放 | // メモリの解放 | ||
mono_free(stringValue); | mono_free(stringValue); | ||
} | |||
</syntaxhighlight> | |||
<br> | |||
===== 戻り値が配列の場合 (非コレクション) ===== | |||
以下の例では、C#ライブラリのメソッドの戻り値はint型の配列であり、C++でそれを受け取っている。<br> | |||
<br> | |||
まず、<code>mono_runtime_invoke</code>関数でC#のメソッドを呼び出して、戻り値を<code>MonoObject*</code>型で受け取る。<br> | |||
次に、<code>reinterpret_cast</code>を使用して<code>MonoObject*</code>型を<code>MonoArray*</code>に変換する。<br> | |||
最後に、<code>mono_array_get</code>関数を使用して<code>int</code>型の配列の各要素を取得している。<br> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
// C#ライブラリ | |||
public int[] RetList() | |||
{ | |||
return [1, 2, 3]; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// C++ | |||
MonoObject *pResult = mono_runtime_invoke(method, instance, nullptr, &exc); | |||
// エラーの確認 | |||
if (exc != nullptr) { | |||
// エラー情報の取得 | |||
// ...略 | |||
} | |||
else { | |||
// MonoObject*型をint型の配列に変換 | |||
MonoArray* resultArray = reinterpret_cast<MonoArray*>(pResult); | |||
// 配列の長さを取得 | |||
auto arrayLength = mono_array_length(resultArray); | |||
// int型の配列に変換 | |||
std::vector<int> ivec(0, 0); | |||
for (auto i = 0; i < arrayLength; i++) { | |||
// MonoArray*型をint型に変換 | |||
ivec.push_back(mono_array_get(resultArray, int, i)); | |||
} | |||
for (auto i : ivec) { | |||
std::cout << i << std::endl; | |||
} | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| 549行目: | 596行目: | ||
MonoString* Field2; // string型 | MonoString* Field2; // string型 | ||
}; | }; | ||
// ...略 | |||
MonoObject *pResult = mono_runtime_invoke(method, instance, params, &exc); | MonoObject *pResult = mono_runtime_invoke(method, instance, params, &exc); | ||
| 557行目: | 606行目: | ||
// ...略 | // ...略 | ||
} | } | ||
else | else { | ||
// タプル型から個々の値を取得 | // タプル型から個々の値を取得 | ||
TupleResult *tupleResult = static_cast<TupleResult*>(mono_object_unbox(pResult)); | TupleResult *tupleResult = static_cast<TupleResult*>(mono_object_unbox(pResult)); | ||
| 842行目: | 890行目: | ||
# [デバッガーの種類]項目を、[混合]または[自動]に設定して、[OK]ボタンを押下する。 | # [デバッガーの種類]項目を、[混合]または[自動]に設定して、[OK]ボタンを押下する。 | ||
<br><br> | <br><br> | ||
{{#seo: | |||
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki | |||
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 | |||
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux | |||
|image=/resources/assets/MochiuLogo_Single_Blue.png | |||
}} | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C++]] | [[カテゴリ:C++]] | ||