0

C#クライアントで使用できるようにしようとしている「通常の」C++コードの本体があります。これを/CLRで正常にコンパイルしました。これだけでは不十分であることがわかりました。マネージコードからコードを呼び出し可能にするには、マネージラッパークラス( "ref")を導入する必要があります。この質問は、refクラスを導入する前に何が起こったかについてです。

ネイティブC++クラスがC#プロジェクトから表示され、次のように記述できることがわかりました。

MyNativeClass mnc = new MyNativeClass();

...ただし、インスタンスでメソッドを呼び出そうとすると、コンパイラによって拒否されました。C#コードを実行したときに、MyNativeClassコンストラクターが呼び出されなかったことがわかりました。実際、mncをインスタンス化しようとしてもコードがまったく生成されなかったため、エラーなしで完了しました。

C#は私のプロジェクトのネイティブタイプをどのように解釈しましたか?コンパイラがインスタンスのインスタンス化を許可したのはなぜですか?メソッドがタイプ自体とは異なる方法で処理されたのはなぜですか?

4

1 に答える 1

1

このコードを機能させるために2つの間違いを犯しました。まず、次のようにC++クラスをpublicと宣言しました。

 public class MyNativeClass {};

これはC++で意味のある構文ではありませんが、C ++/CLIコンパイラで許可されています。publicを省略すると、C#コードCS0122に「保護レベルが原因でFooにアクセスできません」というエラーメッセージが表示されます。

2番目の間違いは、/clrを有効にしてネイティブC++クラスをコンパイルしたことです。これは正常に機能しますが、C ++ 03準拠のコードはILにコンパイルでき、マネージコードと同じように、ジッターによってマシンコードにジャストインタイムでコンパイルされます。そして、同様にうまく実行します。ただし、これを行うのは効率的ではありません。コンパイル時オプティマイザを使用して可能な限り最高のコードを生成できるという利点が失われます。それはまだ最適化されていますが、C++コードオプティマイザーが実行できるほど良い仕事をするために利用できる時間の余裕がないジッターによって今では。これを回避するには、C ++コードを別のソースコードファイルに移動して、/clrを有効にせずにコンパイルできるようにします。または、ソースコードで管理されている#pragmaを使用します。

とにかく、最終的に得られたのは、マネージコンパイラが参照できるMyNativeClassの宣言を実際に含むアセンブリでした。アセンブリでildasm.exeを実行すると、自分で確認できるものがあります。値型タイプとして埋め込まれていることがわかります。コンストラクターもメソッドもない、単なるバイトのブロブ。これは、管理された観点からはC ++オブジェクトに適切に一致し、値型を格納できる場所ならどこにでも格納できるバイトだけです。C#でその型の変数を宣言することは機能しますが、何の役にも立ちません。すべてのバイトが0に設定されたblobを作成するだけです。この宣言の唯一の可能な使用法は、クラスへの型付きポインターを宣言して渡すことができることです。周り、それがすべてです。

于 2013-02-21T11:56:04.860 に答える