dingmaotu / mql-zmq

ZMQ binding for the MQL language (both 32bit MT4 and 64bit MT5)
Apache License 2.0
544 stars 298 forks source link

SUB收不到消息 #2

Closed hohomi closed 7 years ago

hohomi commented 7 years ago

我用下面这段代码订阅信息,为什么一直都收不到任何信息呢? 请您帮我看一下错误在哪里,可以吗?或者可否提供一个订阅所有频道的例子?

void OnStart()
{
   Context context;
   Socket socket(context,ZMQ_SUB);
   bool rc = socket.connect("tcp://localhost:5555");
   socket.setSubscribe("");
   ZmqMsg msg;
   socket.recv(msg);
   Alert(msg.getData());
}
dingmaotu commented 7 years ago

我看了代码,感觉没什么问题。长度为0的subscribe会订阅所有的频道。能否检查一下是否其他原因导致的?比如官方教程中提到的接收方总会漏掉第一条信息?

hohomi commented 7 years ago

这可能是一个bug!因为如果我用下面的2行代码替换“socket.setSubscribe("");”就能收到消息。

char buf[];
zmq_setsockopt(socket.ref(),ZMQ_SUBSCRIBE,buf,0);
dingmaotu commented 7 years ago

是的,我追踪了一下,发现最终是MQL的一个bug导致的

   char u8[];
   Print(ArraySize(u8));//0
   Print(StringLen(""));//0
   StringToCharArray("",u8,0,StringLen(""),CP_UTF8);
   Print(ArraySize(u8));//1

官方文档说明:

StringToCharArray() function includes terminating zero. To exclude it specify the string length explicitely: //--- example of copying of string str to array[] StringToCharArray(str,array,0,StringLen(str));

根据文档,count参数-1时会添加\0,但是为具体长度时不添加字符串结尾。指定为0时,这个函数还是添加了一个字节的\0,导致空字符串转换成了1字节。这个问题需要特殊处理下,遇到空字符串且不需要结尾时直接返回