2012-01-01 5 views
3

管理対象インターフェイスがCOM経由で公開され、ネイティブクライアントによって消費されるシナリオには苦労しています。私は、問題を特定するために管理したのだが、基本的に私はこのようになります小さなプロジェクトを作成して、この問題をシミュレートし、再現するために、不適切な相互運用ランタイムによって整列化された文字列に沸く:COMはBSTRを管理対象サーバーからネイティブクライアントに適切にマーシャリングできません

サーバー:

[ComVisible(true)] 
[Guid("5AF8A86E-B129-4FA0-8B6D-E9DF52DFDD84")] 
public interface IUrlSync 
{ 
    void GetUrl(
     [MarshalAs(UnmanagedType.BStr)] [Out] out string url 
     ); 
} 

[ComVisible(true)] 
[Guid("5AF8A86E-B129-4FA0-8B6D-E9DF52DFDD85")] 
public class Urlsync : IUrlSync 
{ 
    private const string AddressHolderPath = "url.txt"; 

    public Urlsync() 
    { 
     // nothing 
    } 

    public void GetUrl(out string url) 
    { 
     url = File.Exists(AddressHolderPath) ? 
      File.ReadAllText(AddressHolderPath) : null; 
    } 
} 

このクラスをコンパイルします。regasm +ます。gacutil/Iを実行した後、私はこの小さな

ネイティブクライアントを構築しました0

#include <Windows.h> #import "../comstr/bin/release/comstr.tlb" int main(int argc, char* argv[]) { CoInitialize(NULL); { BSTR bstr; HRESULT hr = S_OK; comstr::IUrlSyncPtr sync(__uuidof(comstr::Urlsync)); hr = sync->GetUrl(&bstr); } CoUninitialize(); return 0; } 

ここで、hrの値はS_OKで、bstrはNULL(0x000000)に設定されています。

問題は、私は

管理対象クライアント構築しましたマーシャリング自体とされていることを確認する:

異なるアセンブリからUrlSyncクラスを呼び出します。

 string bstr; 
     comstr.IUrlSync sync = new comstr.Urlsync(); 

     sync.GetUrl(out bstr); 
     Console.WriteLine("the url is: {0}", bstr); 

を予想される文字列を取得しています。 ここには何が欠けていますか?

+0

おそらくうまくいくので、File.Exists()がfalseを返すように、C++ EXEは別のデフォルトディレクトリで実行されています。あなたに期待されるヌル文字列を与えます。 –

答えて

2

私はあなたのサンプルプログラムをビルドし、それが実際に期待どおりに動作することを発見しました。しかし、あなたのプログラムにはいくつかの問題があります。

ファイルが存在しない場合は、現時点ではnullという回答が表示されます。これが事実だろうか?ランタイムフォルダは、追加テストとして作成した管理対象クライアントとは異なる可能性があることを考慮してください。

デバッガで両方のプロジェクトを実行するだけで、何が起こっているのかを確認できます。

の#import文によって生成マーシャラーコードは、あなたがキャッチしない_com_error例外をスローします。

これが役に立ちます。

+0

そうではありませんでした。 URLの値を文字列リテラルに明示的に設定するとNULLイベントが返されました。 –

+1

デバッグを開始することをお勧めします。 「Debugger Type」を「Mixed」に設定すると、ネイティブ・クライアント・コードと管理対象サーバー・コードの両方をデバッグできます。 –

関連する問題