1

marshal_as を調べると、関数呼び出しの 1 つが次の形式を想定しています。

System::String^ const &

const &マネージ ポインターの後の目的は何ですか?

これは私のためにコンパイルされません:

static std::wstring GetString(const System::String^ value)
{
    return msclr::interop::marshal_as<std::wstring>(value);
}

エラー 1 エラー C4996:

'msclr::interop::error_reporting_helper<_To_Type,_From_Type>::marshal_as': この変換はライブラリでサポートされていないか、この変換に必要なヘッダー ファイルが含まれていません。独自のマーシャリング メソッドを追加するには、「方法: マーシャリング ライブラリを拡張する」のドキュメントを参照してください。c:\program files (x86)\microsoft Visual Studio 9.0\vc\include\msclr\marshal.h 203

これは次のことを行います。

static std::wstring GetString(const System::String^ value)
{
    return msclr::interop::marshal_as<std::wstring>(const_cast<System::String^>(value));
}
4

1 に答える 1

3

marshal_as メソッドは、次のテンプレートによって定義されます。

template <class _To_Type, class _From_Type>
inline _To_Type marshal_as(const _From_Type&);

エクストラの主な目的は、const &このテンプレート宣言に準拠することです。

これは、関数の呼び出し方法に影響します。IL を確認したところ、String^予想どおり const 間接参照として渡されましたが、これは大きな変更ではありません。

メソッドがスタンドアロンの場合、おそらく なしで宣言され、const &違いはほとんどありません。


String^ const &を使用してメソッドを呼び出そうとしていString^ constます。コンパイラは、その変換を自動的に (安全に) 行うことはできません。

const_cast で行っていることは、String^ constを通常の に変えることですString^。コンパイラは、安全かつ自動的に変換できます。String^String^ const &

constローカル メソッド宣言から を削除するだけです。これは私のためにコンパイルされます:

static std::wstring GetString(System::String^ value)
{
    return msclr::interop::marshal_as<std::wstring>(value);
}

コンパイラがその変換を行うことができないのはなぜですか? String^ const &const String^ const &は同じものではないことに注意してください。最初のものは「文字列オブジェクトへの定数ポインタ」と言います。2 つ目は、「定数文字列オブジェクトへの定数ポインタ」です。を使用したメソッドで(const System::String^ value)は、定数文字列オブジェクトがあり、呼び出している関数は非定数文字列オブジェクトへのポインターを期待しています。String クラスが不変であることはわかっていますが、コンパイラはそうではありません。そのため、オブジェクトが非 const であると考えるメソッドに const オブジェクトへのアドレスを渡しません。

(私は Visual Studio 2010 SP1 を使用していますが、2008 年から 2010 年の間にマーシャル メソッドに大きな変更があったとは思いません。)

于 2013-01-31T16:06:19.833 に答える