3

COMを介して公開され、ネイティブクライアントによって使用されるマネージドインターフェイスがあるシナリオで苦労しています。私はなんとか問題を切り分けました、そしてそれは基本的に相互運用ランタイムによって不適切にマーシャリングされている文字列に要約されます、この問題をシミュレートして再現するために私は次のような小さなプロジェクトを作成しました:

サーバ:

[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を実行した後、私はこれを小さく構築しました

ネイティブクライアント:

#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);

期待される文字列を取得しています。私がここで欠けているものは何ですか?

4

1 に答える 1

2

サンプルプログラムを作成しましたが、実際には期待どおりに機能することがわかりました。ただし、プログラムにはいくつかの問題があります。

ファイルが存在しない場合は、実際に現在発生しているnull応答を受け取ります。これは本当でしょうか?ランタイムフォルダは、追加のテストとして作成した管理対象クライアントとは異なる場合があることを考慮に入れてください。

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

#importステートメントによって生成されたマーシャラーコードは、キャッチしない_com_error例外をスローします。

お役に立てれば。

于 2012-01-03T22:47:45.693 に答える