「C++の応用 - C Sharp DLLの使用」の版間の差分

ナビゲーションに移動 検索に移動
362行目: 362行目:
   
   
     return 0;
     return 0;
}
</syntaxhighlight>
<br>
==== 戻り値がある場合 ====
===== 戻り値がint型の場合 =====
C#ライブラリが戻り値を返す場合は、<code>mono_runtime_invoke</code>関数でC#のメソッドを呼び出して、戻り値を<code>MonoObject*</code>型で受け取る。<br>
その後、<code>mono_field_get_value</code>関数を使用して、<code>MonoObject*</code>型のオブジェクトからint型の戻り値を取得する。<br>
<br>
<u>※注意</u><br>
<u><code>mono_runtime_invoke</code>関数の戻り値は<code>MonoObject*</code>型であるため、実際のint型のデータは内部的には<code>m_value</code>と呼ばれる領域に格納されていることである。</u><br>
<u>これにより、int型の戻り値を取り出すことができる。</u><br>
<br>
<syntaxhighlight lang="c++">
// C#ライブラリがint型の戻り値を返す場合
MonoObject *pResult = mono_runtime_invoke(method, instance, params, &exc);
// エラーの確認
if (exc != nullptr) {
    // エラー情報の取得
    // ...略
}
else
{
    // int型に変換
    int returnValue;
    mono_field_get_value(result, mono_class_get_field_from_name(mono_object_get_class(result), "m_value", "System.Int32"), &returnValue);
    // 結果を出力
    std::cout << "Method result: " << returnValue << std::endl;
}
</syntaxhighlight>
<br>
===== 戻り値がstring型の場合 =====
以下の例では、<code>mono_runtime_invoke</code>関数でC#のメソッドを呼び出して、戻り値を<code>MonoObject*</code>型で受け取る。<br>
次に、<code>reinterpret_cast</code>を使用して<code>MonoObject*</code>型を<code>MonoString*</code>に変換する。<br>
最後に、<code>mono_string_to_utf8</code>関数を使用して<code>string</code>型の戻り値を取得している。<br>
<syntaxhighlight lang="c++">
// C#ライブラリがstring型の戻り値を返す場合
MonoObject *pResult = mono_runtime_invoke(method, instance, params, &exc);
// エラーの確認
if (exc != nullptr) {
    // エラー情報の取得
    // ...略
}
else
{
    // string型に変換
    MonoString *resultString = reinterpret_cast<MonoString*>(result);
    const char* stringValue = mono_string_to_utf8(resultString);
    // 結果を出力
    std::cout << "Method result: " << stringValue << std::endl;
    // メモリの解放
    mono_free(stringValue);
}
</syntaxhighlight>
<br>
===== 戻り値がタプル型の場合 =====
タプル型において、C#からC++に直接渡すことは難しいため、複数の戻り値を配列や構造体で受け取る必要がある。<br>
もし可能であれば、代わりに複数の引数を使用して値を取得することを検討することもできる。<br>
<br>
以下の例では、タプル型 (int, string) の戻り値を配列として受け取り、各要素を取り出している。<br>
<u>ただし、戻り値の型や順序に依存するため、メソッドが変更されると対応が必要となることに注意する必要がある。</u><br>
<br>
<syntaxhighlight lang="c++">
// C#ライブラリがタプル型の戻り値を返す場合
MonoObject *pResult = mono_runtime_invoke(method, instance, params, &exc);
// エラーの確認
if (exc != nullptr) {
    // エラー情報の取得
    // ...略
}
else
{
    // タプル型から個々の値を取得
    MonoArray *resultArray = reinterpret_cast<MonoArray*>(result);
    TupleResult tupleResult;
    tupleResult.intValue    = *reinterpret_cast<int*>(mono_array_addr(resultArray, int, 0));
    tupleResult.stringValue = mono_string_to_utf8(reinterpret_cast<MonoString*>(mono_array_addr(resultArray, MonoString*, 1)));
    // 結果を出力
    std::cout << "Method result: " << tupleResult.intValue << ", " << tupleResult.stringValue << std::endl;
    // メモリの解放
    mono_free(tupleResult.stringValue);
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>

案内メニュー