2016-12-23 9 views
2

は、私はこのようなstd::stringに管理し、文字列をマーシャリングすることができmarshal_cppstd.hmsclr::interop::marshal_as<>を使用したクラスメンバーから文字列を管理しますやったときに、単にこれは:マーシャリングは

std::string unmanaged = marshal_as<std::string>(this->managed); 

エラーは言う:

「msclr ::相互運用:: marshal_as」:オーバーロードされた関数「marshal_as」のインスタンスは、引数リスト

またはコンパイラエラーC2665などに一致する3つのオーバーロードのどれもすべて変換することができませんでした引数の型

私はヘルパー変数を使用するようにコードを変更すると、それが動作:

String^ localManaged = this->managed; 
std::string unmanabed = marshal_as<std::string>(localManaged); 

ここに暗黙的なキャスティングがあるはずですね。なぜこれが起こり、どうすれば簡単なワンライナーの仕事をすることができますか?

+1

@LucasTrzesniewskiこれがコンパイラのバグであるかどうかは不明ですが、ここでも同様のことが書かれています。http://stackoverflow.com/questions/30529869/marshal-to-stdstring-from-systemstring-member-of-struct- handle?rq = 1私はクラスを使用していますが、これは関連している可能性があります。 – ZoolWay

+0

私は、署名が 'System :: String^const&'パラメータを受け取り、 '&'が可動オブジェクトへの参照を使用できないことに気付かなかった。確かに、コンパイラのバグではなく、メソッドのシグニチャが与えられたときには完全な意味を持ちます。ですから、 'System :: String ^'パラメータを取るヘルパーメソッドを書いてください。 –

答えて

3

ええ、それはかなりひどいエラーメッセージで、実際の問題を発見するのに役立ちません。テンプレートのエラーメッセージは、しばしば理解しにくいものです。あなたはコンパイラが引数の型と一致し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->managedcopyの間に大きな違いがあることです。例^のようなオブジェクトでは、thisポインタが安定していません。このコードが実行されている間に値が変更される可能性があります。ガベージコレクションがトリガーされたときに発生します。ほとんどのプログラムでオッズはありませんが、ゼロではありません。プログラム内の別のスレッドがGCヒープから割り当てを行い、コレクションをトリガしたときに発生します。一年に一度起こることのようなもの。

marshal_as <>()がその仕事をしているのとまったく同じようにコレクションが行われると、それは非常に悲惨です。アンマネージ参照は無効になり、GCがヒープを圧縮した後にガベージを指し示します。 C++/CLIコンパイラはこれを実現させることができないので、_From_Type&の代用としてはthis->managed&を考慮しません。決してそれを見ない。テンプレートの特殊化はどちらにも一致しません.C2665は必然的な結果です。

copy引数の大きな大きな違いは、アドレスが常に安定していることです。最適化されていないコードでスタックフレームに格納されます。オプティマイザで処理された後にCPUレジスタに格納されることがよくあります。従ってcopy&であり、_From_Type&の代わりに有効です。コンパイラは問題なくテンプレートコードを生成できます。

あなたが見つけた回避策は完全に有効であり、これを行う最適な方法です。コンパイラがちょうど私たちのためにこれをした場合、いいですか、それはないです。エイリアシングの問題もうまくいきません。値をコピーしなければならないこともあります。 C++/CLIコードの作成と管理コードとネイティブコードの混在の結果について知っておかなければならないことはありません。

関連する問題