2016-11-07 3 views
4

2つのパラメータを持つtestというメソッドを持つCOM DLLを呼び出すC#プログラムがあります。最初のパラメータにはByValが渡され、2番目にはByRefが渡されます。ByRefを使用したCOM Interopメソッドのシグネチャ

これは、COM DLLが何をするかです:

Public Sub test(ByVal a As String, ByRef b As String) 
    a = "a" 
    b = "b" 
End Sub 

これは、C#のプログラムが何をするかです:

test.Class1 x = new test.Class1(); 
      string a = "1"; 
      string b = "2"; 
      x.test(a, ref b); 

私はrefキーワードを削除した場合、コンパイラは私をすることをアドバイスしないことに注意してくださいrefキーワードが欠けて、パラメータByValを渡しました。 refが欲しいと分かるまで気づかないので、これは大きな問題になる可能性があります。なぜコンパイラがこの動作を示すのか知っていますか?

+0

@MartinVerjans C#プロジェクトでは "Option Strict ON"はありません – CRK

+0

@HansPassant私はrefキーワードなしでプログラムをテストし、文字列の値は変更しません。したがって、ByRefの代わりに文字列Byvalを渡してください。 – CRK

答えて

5

これは、COM相互運用コードとC#言語バージョン4以降に固有のものです。はい、この特定のケースではrefを省略することができます。 C#バージョン4には、Officeプログラミングを簡単にするための調整がたくさんありました。 Office APIはもともとVBの初期バージョンでうまく動作するように設計されていたため、デフォルトでByRefを使用していました。まだVBAの場合。そのため、実際に渡された引数を変更していないにもかかわらず、APIには、lotのメソッドパラメータByRefがあります。

コンパイラは、必要に応じてコールを有効にするために一時変数を生成します。あなたの変数が更新されないという結果になります。あなたが気をつけなければならないことがあります。 2ステップ前進、1ステップ後ろ:)

+0

大きなプロジェクトがあり、見つからなかった "ref"キーワードをすべてチェックしたいのですが、どうすればいいですか?それとも、間違いのアドバイスですか? – CRK

+0

Hmya、あなたはコード内のバグを見つけるために明白な方法を使用する必要があります、あなたはデバッガを使用します。パニックに陥らないでください。間違っているからといって、間違っているとは限りません。 IntelliSenseを使用すると、正しい結果が得られます。そのCOMコードを最初に修正してください、それはもちろん関数でなければなりません。 –

+0

あなたは私の問題を理解していないかもしれません。これは問題です:COMメソッドのシグネチャでrefキーワードが見つからない場合、実際にメソッドがByRefパラメータを必要としても、コンパイラはそれを受け付けません。大きなプロジェクトでは、すべての方法をチェックすることはできませんし、署名もしています(時間はかかります)。 refキーワードが見つからない場合はコンパイラのアドバイスが必要です。 – CRK

関連する問題