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

我已经构建了您的示例程序,发现它实际上可以按预期工作。但是,您的程序存在一些问题。

如果文件不存在,您实际上会得到当前遇到的响应。会是这样吗?考虑到运行时文件夹可能与您作为额外测试构建的托管客户端不同。

您可以简单地在调试器中单步调试这两个项目,看看发生了什么。

#import语句生成的编组器代码会引发您没有捕获的_com_error异常。

希望这可以帮助。

于 2012-01-03T22:47:45.693 回答