2017-12-04 48 views
0

私はC++/cliプログラミングの新人です。今日は私のプロジェクトの一つでgcrootに出くわして、その使い方と混同しました。 見つかりましたgcrootGChandleのラッパーです。管理対象オブジェクトが参照されているので、オブジェクトが削除されないようにガベージコレクタに通知します。ネイティブC++関数の内部でgcrootは必要ですか?

gcrootを使用すると、ネイティブクラスのプロパティを宣言して管理オブジェクトへの参照を保持することが理にかなっています。

int NativeFunction() 
{ 
    gcroot<ManagedType^> xx = gcnew ManagedType(); 
    return xx->FunctionCalled(); 
} 

は、実装のこの種のは良い習慣です。しかし、私はgcrootも以下のようなプロジェクトではどこでも使用されましたか?ここでgcrootを使用する必要がありますか?

私はのように、gcrootなしxxを宣言した場合:

ManagedType^ xx = gcnew ManagedType(); 

は、それがどんな問題を作成していますか?

答えて

1

ここには複数のレベルの間違いがあります。死んで間違っていることから始めて、あなたは正しいです、gcroot<>を使用することは全く不必要で、積極的に有害です。これはGCHandleのラッパーです。実行時にGCHandle :: Alloc()、GCHandle :: ToIntPtr()、GCHandle :: FromIntPtr()、GCHandle :: Free()を呼び出します。何のメリットもないので、GCはManagedTypeオブジェクトリファレンスを何の助けもなく見つけることができます。ジャストインタイムコンパイラの主な任務。あなたの代理人は大丈夫です。

それでは、何の不公平な誤りがありますか?パラメータのないManagedTypeコンストラクタによってどのような魔法が実行されていますか?このコードの作成者は、staticキーワードが有用であったはずであることを認識していないことは間違いありません。だから彼はManagedType :: FunctionCalled()を書くだけで、オブジェクトを完全に割り当てることを避けることができました。 gcrootにあまりにも多くの頼りにしているのは確かに彼がそれを見るのを妨げていたでしょう。

次に、この「ネイティブコード」を呼び出すという厄介な問題があります。そうではなく、/ clrや#pragmaを有効にしてコンパイルする必要があります。実行時にコンパイルされたジャストインタイムでなければならないMSILが生成されます。管理されたコードとまったく同じです。しかし、マネージコードの利点がなければ、ネイティブコードと同じように検証できません。ネイティブコードの利点のどれも、あなたは余分なオプティマイザの愛を得ることはありません。このことは、ライブラリ全体が/ clrを有効にしてコンパイルされると、悪くなる傾向があります。残念なことに、デザイナーはそれを気付かせるために仕事をあまりにもうまくやっただけで、パフォーマンスの低下を観察するだけでした。

適切な方法は、ネイティブコードが常にこれを行う方法です。関数ポインタ。 Marshal :: GetFunctionPointerForDelegate()で必要なものを取得します。しかし、正しく記述することは難しく、perf問題を解決する必要がある場合を除き、作業コードで考慮する必要はありません。

関連する問題