ええ、それはかなりひどいエラーメッセージで、実際の問題を発見するのに役立ちません。テンプレートのエラーメッセージは、しばしば理解しにくいものです。あなたはコンパイラが引数の型と一致しmarshal_as <>テンプレート関数のバージョンを見つけようとして働い見に出力ウィンドウに見ている
#include "stdafx.h"
#include <string>
#include <msclr\marshal_cppstd.h>
using namespace System;
using namespace msclr::interop;
ref class Example {
String^ managed;
public:
void test() {
auto bad = marshal_as<std::string>(this->managed); // C2665
auto copy = this->managed;
auto good = marshal_as<std::string>(copy);
}
};
:それはいくつかのREPROのコードを使用することができます。 2つのテンプレート特殊化を考慮して表示されますが、ではなく、が必要です。これは次のとおりです。
template <class _To_Type, class _From_Type>
inline _To_Type marshal_as(const _From_Type&);
_From_Type&
引数はトラブルメーカーである、それは管理されていない参照、&
でどのように注意してください。追跡参照とは対照的に、%
。または単に平文^
は、System :: Stringのような参照型になります。
参照することとの間に大きな違いがあることは、this->managed
とcopy
の間に大きな違いがあることです。例^のようなオブジェクトでは、this
ポインタが安定していません。このコードが実行されている間に値が変更される可能性があります。ガベージコレクションがトリガーされたときに発生します。ほとんどのプログラムでオッズはありませんが、ゼロではありません。プログラム内の別のスレッドがGCヒープから割り当てを行い、コレクションをトリガしたときに発生します。一年に一度起こることのようなもの。
marshal_as <>()がその仕事をしているのとまったく同じようにコレクションが行われると、それは非常に悲惨です。アンマネージ参照は無効になり、GCがヒープを圧縮した後にガベージを指し示します。 C++/CLIコンパイラはこれを実現させることができないので、_From_Type&
の代用としてはthis->managed&
を考慮しません。決してそれを見ない。テンプレートの特殊化はどちらにも一致しません.C2665は必然的な結果です。
copy
引数の大きな大きな違いは、アドレスが常に安定していることです。最適化されていないコードでスタックフレームに格納されます。オプティマイザで処理された後にCPUレジスタに格納されることがよくあります。従ってcopy&
はであり、_From_Type&
の代わりに有効です。コンパイラは問題なくテンプレートコードを生成できます。
あなたが見つけた回避策は完全に有効であり、これを行う最適な方法です。コンパイラがちょうど私たちのためにこれをした場合、いいですか、それはないです。エイリアシングの問題もうまくいきません。値をコピーしなければならないこともあります。 C++/CLIコードの作成と管理コードとネイティブコードの混在の結果について知っておかなければならないことはありません。
@LucasTrzesniewskiこれがコンパイラのバグであるかどうかは不明ですが、ここでも同様のことが書かれています。http://stackoverflow.com/questions/30529869/marshal-to-stdstring-from-systemstring-member-of-struct- handle?rq = 1私はクラスを使用していますが、これは関連している可能性があります。 – ZoolWay
私は、署名が 'System :: String^const&'パラメータを受け取り、 '&'が可動オブジェクトへの参照を使用できないことに気付かなかった。確かに、コンパイラのバグではなく、メソッドのシグニチャが与えられたときには完全な意味を持ちます。ですから、 'System :: String ^'パラメータを取るヘルパーメソッドを書いてください。 –