2016-04-22 23 views
0

C++からC#コードを呼び出そうとしています。そこで私はCOM Interopの方法を選択しました。今、私はC#のコードがあります。私はこのコンパイルをしようとするとC#からC#を呼び出し、戻り値

namespace ToBeCalled 
{ 
    [Guid("9329feaf-b293-4093-a7d8-6128f52b30a6")] 
    [ComVisible(true)] 
    public interface IInterface 
    { 
     int Write(string toWrite); 
    } 
} 

namespace ToBeCalled 
{ 
    [Guid("e4105e40-2d6b-4b7c-ae42-d2f9c405a2a0")] 
    [ComVisible(true)] 
    public class ClassYouWantToUse : IInterface 
    { 
     public int Write(string toWrite) 
     { 
      System.Console.WriteLine(toWrite); 
      return 1; 
     } 
    } 
} 

とC++コード

#import "...\\ToBeCalled.tlb" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    // Initialize COM. 
    HRESULT hr = CoInitialize(NULL); 

    // Create the interface pointer. 
    ToBeCalled::IInterfacePtr piTest(__uuidof(ToBeCalled::ClassYouWantToUse)); 

    long lResult = 0; 

    // Call the Add method. 
    piTest->Write("hi", &lResult); 

    wprintf(L"The result is %d\n", lResult); 

    // Uninitialize COM. 
    CoUninitialize(); 
    return 0; 
} 

を、もちろんそれは、Writeは2つの引数を取らないことを言います。私はMSDNを見ました。ここでは、このような例があり、このように戻り値を取ります。だから私の質問は、どのように私は関数の戻り値を取得できますか?電話を

piTest->Write("hi"); 

に更新すると、未処理の例外で実行が失敗します。戻り値なしでこの例を試したとき、メソッドの戻り値の宣言が無効であるため、すべてが正常に機能します。

+0

私はパラメータをc#に追加する必要があることを発見しました。次に、結果値を持つ関数に2番目の引数を使用できます。さて、Intのために問題は解決しましたが、どうすればこのような文字列を送ることができますか? –

+0

'[out]'パラメータではなく、通常は値を返すことができます。まさに例外は何ですか?あなたはマネージドコールをデバッグしましたか? –

答えて

2

サーバーコードはOKで、outパラメータを使用する必要はありません。

クライアントコードは単純に次のようになります。

long Write(_bstr_t toWrite); 

これは、生成されたラッパーコードです:あなたが内部で生成された.tlhファイルを見れば

long result = piTest->Write("hi"); 

、あなたはその署名のようなものであることがわかりますあなたはおそらくtlhファイルの一部であり、次のような生のCOM呼び出しと混同している可能性があります。

virtual HRESULT __stdcall raw_Write(BSTR toWrite, long* pRetVal) = 0; 

ラッパーは、内部的に未処理のCOM呼び出しを呼び出して戻り値を処理するため、戻り値は通常は([out, retval]引数ではなく)関数から戻されます。生の呼び出しの結果エラー(a failed HRESULT)を示します。_com_error例外がスローされます。

詳細については、ラッパーメソッドの実装を含むtli拡張子を持つ別の生成ファイルをご覧ください。

+0

ありがとう、私はそれを試してみてください。はい、私はHRESULTと混同されました。私はC#から文字列を返すときに、ここでいくつかの割り当てを解除する必要がありますか?はいの場合、どうですか? –

+1

文字列を返さないので、割り当てを解除することはありません。 ( 'idl'定義で' [out、retval] '引数として定義された)文字列を返す新しいメソッドを作成した場合、標準のCOMルールに準拠しており、一般的には' SysFreeString' APIを介して割り当てを解除する必要があります例:生の呼び出しを使用する場合)。しかし、 '#import'は' bstr_t'を返す 'スマート'ラッパーも生成します。これはあなたのためにそれを解放するので、そのメソッドを使用すると割り当てを解除することはありません。 –

関連する問題