我在一个场景中苦苦挣扎,我有一个通过 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);
我得到了预期的字符串。我在这里缺少什么?