- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试通过 C++ 中的 MSMQ 消息发送 COM 对象。这是我的对象:
class ATL_NO_VTABLE CAnalisis : public CComObjectRootEx, public CComCoClass, public ISupportErrorInfo, public IDispatchImpl, public IPersistStreamInit{private: typedef struct { DOUBLE size; float color; float light; BSTR imgName; BSTR uname; } Image; Image img; STDMETHOD(Load)(IStream *pStm); STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty);
一切顺利,我可以获得整个对象,但 BSTR 类型除外。正确发送和接收 float 和整数。但是 BSTR 类型不起作用。我正在尝试发送字符串,但找不到方法。我确实尝试使用 VARIANT,但结果也是错误的。不知何故,看起来字符串没有序列化。
这些是我的 ATL 组件的一些获取和设置函数:
这个很好用:
STDMETHODIMP CAnalisis::getLight(FLOAT* light){ *light=img.light; return S_OK;}STDMETHODIMP CAnalisis::setLight(FLOAT light){ img.light=light; return S_OK;}
这个没有:
STDMETHODIMP CAnalisis::getImgName(BSTR* imgName){ *imgName = img.imgName; return S_OK;}STDMETHODIMP CAnalisis::setImgName(BSTR imgName){ img.imgName=imgName; return S_OK;}
这就是我创建 MSMQ 消息并在我的生产者中填充值的方式:
// For these ActiveX components we need only smart interface pointer IMSMQQueueInfosPtr pQueueInfos; IMSMQQueueInfoPtr pQueueInfo; IMSMQQueuePtr pQueue; IUnknownPtr pIUnknown; // Instanciate the follwing ActiveX components IMSMQQueryPtr pQuery(__uuidof(MSMQQuery)); IMSMQMessagePtr pMessage(__uuidof(MSMQMessage)); IAnalisisPtr pAnalisis(__uuidof(Analisis)); WCHAR * imagen; imagen = L"imagen1.jpg"; pAnalisis->setImgName(imagen); (...) pAnalisis->setFruitSize(20.00); (...) pQueueInfo = new IMSMQQueueInfoPtr( __uuidof(MSMQQueueInfo) ); pQueueInfo->PathName = "MYCOMPUTER\\private$\\myprivatequeue"; pQueue = pQueueInfo->Open(MQ_SEND_ACCESS, MQ_DENY_NONE); pMessage->Body = static_cast(pAnalisis); pMessage->Send(pQueue);
这是序列化代码
STDMETHODIMP CAnalisis::Load( IStream *pStm ){ ULONG cb; HRESULT hr; if (NULL==pStm) return ResultFromScode(E_POINTER); // Read an object from the stream. // hr=pStm->Read(&img, sizeof(Image), &cb); if (FAILED(hr)) return hr; if (sizeof(Image) != cb) return E_FAIL; return NOERROR;}STDMETHODIMP CAnalisis::Save( IStream *pStm, BOOL bClearDirty ){ ULONG cb; HRESULT hr; if (NULL==pStm) return ResultFromScode(E_POINTER); // Write an object into the stream. hr=pStm->Write(&img, (ULONG)sizeof(Image), &cb); if (FAILED(hr) || sizeof(Image)!=cb) return ResultFromScode(STG_E_WRITEFAULT); return NOERROR;}
如果我在生产者中获得 BSTR 值(在序列化之前),pAnalisis-getImgName()
,它工作正常。相反,当我尝试在消费者中获取它时,从队列中读取消息后,它不会返回任何内容。其他值(例如大小)可以毫无问题地返回。
有谁知道如何通过 MSMQ 在 COM 对象中发送 BSTR 值?
我试图找到一些类似的例子,但完全是徒劳的。
问题是我得到的要么是一个非常奇怪的带有奇怪字符的值,要么是一个十六进制值,这取决于我如何提取该值..问题是我从来没有得到正确的值。
但是我想知道...我们确定可以发送 BSTR 值吗?如果我没记错的话,它是一个指向字符串的指针......我正在运行两个不同的进程(即生产者和消费者),所以它们使用不同的内存块,并且它们应该在不同的机器上运行。 ..
我试图将此信息作为 VARIANT 类型发送.. 但也迷路了。然而,这似乎没有发送 BSTR 那么牵强。
对此有什么想法吗?
最佳答案
问题在于 Image 类的序列化将其视为连续的内存块。由于 BSTR 实际上是一个指针,因此只有指针值被序列化并且 BSTR 有效负载丢失。
相反,您应该将除 BSTR 之外的所有字段写为二进制文件并分别处理 BSTR。例如,您可以先将 BSTR 长度写为整数,然后再写它的有效负载。读取时先读取长度,调用SysAllocStringLen()分配缓冲区,再读取payload。
保持简单字段的序列化(IPersistStreamInit::Save()):
pStm->Write(&(img.color), (ULONG)sizeof(float), &cb);
对于 BSTR,执行此操作:
int length = SysStringLen( img.uname );
pStm->Write(&length, (ULONG)sizeof(int), &cb);
if( length > 0 ) {
pStm->Write( img.uname, (ULONG)(length * sizeof(WCHAR) ), &cb);
}
类似于读取(IPersistStreamInit::Load()):
int length;
pStm->Read(&length, (ULONG)sizeof(int), &cb);
if( length > 0 ) {
img.uname = SysAllocStringLen( 0, length );
pStm->Read( img.uname, (ULONG)( length * sizeof( WCHAR) ), &cb);
} else {
img.uname = 0;
}
请注意,此代码写入/读取字符串长度,然后写入/读取由 Unicode 字符组成的有效负载。每个 Unicode 字符占用超过一个字节 - 因此 IStream 读/写方法调用中的乘法。
关于c++ - 在 MSMQ 消息中发送具有 BSTR 值类型的 COM 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/627254/
我刚刚和一位 Microsoft MVP 聊天,他告诉我 MSMQ 已经过时了。这是真的?那么 SOA 的基础设施是什么??? 最佳答案 好吧,他们发布了一个带有 Vista 的新版本 (4.0),它
只是想确认如何将消息发送到远程事务性消息队列。 假设我有两台机器,A 和 B。 机器 A 有一个用于接收消息的事务队列。 Windows 服务监视此队列并对数据执行某些操作(将其保存到 SQL Ser
我一直看到documentation表示不可能发送到事务范围之外的远程事务 msmq 队列。我发现这很难相信,因为我认为我已经这样做了好几个星期了。我有一个小应用程序,它将消息发布到事务性的远程队列。
我正在使用 MSMQ 传输一个 byte 数组。 格式化程序是一个 BinaryMessageFormatter。 目标队列是私有(private)队列,我正在使用直接 TCP 通信。 目标机器在不同
有人可以为我指出一些关于为队列集群设置 MSMQ 的好资源吗?我有兴趣帮助: 实际设置集群MSMQ节点,并使其运行 设置应用程序以将消息发送到集群队列。 设置应用程序(至少 2 个)以从同一个集群队列
我是消息传递的新手,有点不清楚 MSMQ 是否可以为事务队列传递乱序消息。我想这一定是因为如果一条消息没有得到正确处理(并且因为我们将使用多个“竞争消费者”),那么其他消费者可以继续处理消息,同时将失
我们使用 BizTalk Server 通过 MSMQ 发送消息。接收系统要求每条消息都将扩展属性设置为 guid(作为字节数组)。 MSDN 记录了 MSMQMessage here 的 Exten
我正在做 NServiceBus 网站 ( http://docs.particular.net/samples/step-by-step/ ) 上的示例,当我在 Visual Studio 中运行时
我们有一个基于 NServiceBus 的 Pub/Sub 系统,我们有间歇性问题,消息无限期地卡在发布者传出队列上,而不是被传输到订阅者输入队列。 注意事项: 当我们重新启动发布者服务和订阅者服务时
当您向远程队列发送消息时,会在您自己的机器上创建一个临时传出队列。这是否意味着如果您自己的机器上没有安装MSMQ,您就不能使用远程队列? 最佳答案 你是对的。如果你自己的机器上没有安装 MSMQ,你就
我正在尝试使用以下路径连接到远程私有(private) MSMQ 队列: "FormatName:DIRECT=OS:remoteMachineName\Private$\MyQueue" 我收到以下
据我从文档中看到,您应该检查消息队列中是否有消息的方法是使用 Peek 方法。然后,您依靠它失败并返回 MessageQueueException 来告诉您队列为空。 public bool
我正在尝试使用主机文件中的别名指向包含 MSMQ 的服务器。如果我在 MSMQ 路径中指定实际服务器名称,则一切正常: var queue = new MessageQueue("FormatName
是否可以直接从队列中以字符串形式读取消息(与您在计算机管理 MSC 管理单元中查看 MSMQ 消息时看到的消息正文相同),以便我可以自己将其保存到数据库中?我希望能够存储它以便稍后重播而不会丢失任何数
有没有办法清除传出队列。似乎我无法使用 MMC 管理单元完成此操作,当我尝试在代码中清除它时出现错误 Format name is invalid将消息发送到的计算机不存在,因此它们永远不会被发送,但
有一个名为 queue1 的公共(public)队列在机器 A 上。我想从机器 B 向这个队列发送消息。为了实现这一点,我编写了那个 c# 代码。 if (MessageQueue.Exists("m
是否有某种标准配置设置、服务或工具可以接受来自一个队列的消息并将其移至另一个队列?自动处理死消息问题,并提供一些重试能力?我想这就是“MSMQ 消息路由”所做的事情,但似乎找不到有关它的文档(Wind
我正在尝试创建一个 MSMQ 解决方案,对于某些消息,我希望它们仅在下午 6 点之后处理,那么 MSMQ 中是否有一种方法可以在 Future 中处理该消息? 最佳答案 队列是一种先进先出的数据结构。
我们的系统中有许多 MSMQ 队列,包括私有(private)队列和公共(public)队列。有时,从队列中读取的 Windows 服务会崩溃,因此消息会在该队列中堆积。一旦队列达到一定大小(可能是
我们在使用 NServiceBus 的负载平衡的高容量环境中遇到了 MSMQ 问题。 我们的环境如下所示: 1 F5 通过循环分配网络流量到 6 个应用服务器。这 6 个服务器中的每一个都使用一个 B
我是一名优秀的程序员,十分优秀!