COM无法正确地从托管服务器封送BSTR到本机客户端

本文关键字:BSTR 客户端 本机 服务器 正确地 COM | 更新日期: 2023-09-27 18:19:21

我正在努力解决这样一个场景:我有一个通过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);

得到预期的字符串。我错过了什么?

COM无法正确地从托管服务器封送BSTR到本机客户端

我已经构建了您的示例程序,并发现它实际上如预期的那样工作。但是你的程序有一些问题。

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

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

#import语句生成的编组程序代码会抛出_com_error异常,您无法捕获。