COM无法正确地从托管服务器封送BSTR到本机客户端
COM fail to properly marshal a BSTR from a managed server to native client
我正在努力解决这样一个场景:我有一个通过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);
得到预期的字符串。我错过了什么?
我已经构建了您的示例程序,并发现它实际上如预期的那样工作。但是你的程序有一些问题。
如果该文件不存在,则实际得到当前遇到的null响应。这是真的吗?请考虑运行时文件夹可能与您作为额外测试构建的托管客户端不同。
您可以简单地在调试器中遍历两个项目,看看发生了什么。
由#import语句生成的编组程序代码会抛出_com_error异常,您无法捕获。
相关文章:
- "unknown ca"自生成的 CA、证书和客户端/服务器
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 使用调试/崩溃报告将应用程序部署到客户端
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 从服务器传输到客户端的消息不会出现
- OpenSSL TLS服务器-使用客户端证书白名单
- 当服务中的事件被触发时,如何将响应从服务发送回客户端?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 提升 Asio TCP 服务器 处理多个客户端
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何绑定 C++ gRPC 客户端的网络接口
- C++套接字客户端到 Python 服务器未创建连接
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 将相机数据从服务器实时流式传输到客户端
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- GRPC C++ TLS 客户端 grpc::SslCredentials() 方法不返回
- 计算出有多少客户端可以连接到我正在使用的一些tcp服务器代码
- 如何暂停插孔音频客户端
- COM无法正确地从托管服务器封送BSTR到本机客户端