zmq_getsockopt Windows x64上,当ZMQ_FD option_val的本地转

2019-10-18 14:00发布

Windows x64上传递一个局部变量的地址zmq_getsockopt为ZMQ_FD始终如一地EINVAL。 下面的代码可能是最小的重现该问题。

#include <zmq.h>                                                                                                                                                                                                   
#include <stdio.h>                                                                                                                                                                                                 

void zmq_perror(const char*);                                                                                                                                                                                      

int main(void)                                                                                                                                                                                                     
{                                                                                                                                                                                                                  
    const char *endpoint = "tcp://127.0.0.1:7100";                                                                                                                                                                 

    void *ctx    = zmq_ctx_new();                                                                                                                                                                                  
    if (ctx == NULL) { zmq_perror("zmq_ctx_new"); }                                                                                                                                                                

    void *socket = zmq_socket(ctx, ZMQ_DEALER);                                                                                                                                                                    
    if (socket == NULL) { zmq_perror("zmq_socket"); }                                                                                                                                                              

    int rc;                                                                                                                                                                                                        

    rc = zmq_connect(socket, endpoint);                                                                                                                                                                            
    if ( rc == -1 ) { zmq_perror("zmq_connect"); }                                                                                                                                                                 


    /*** This results in EINVAL ***/                                                                                                                                                                                                               
    int fd;                                                                                                                                                                                                      
    size_t fd_size = sizeof (fd);                                                                                                                                                                                
    rc = zmq_getsockopt(socket, ZMQ_FD, &fd, &fd_size);                                                                                                                                                          
    if (rc == -1) { zmq_perror("zmq_getsockopt"); }                                                                                                                                                              


    /*** This works without issue ***/
    /*                                                                                                                                                                                                           
    int *fd        = malloc(sizeof(int));                                                                                                                                                                          
    size_t fd_size = sizeof (fd);                                                                                                                                                                                  
    rc = zmq_getsockopt(socket, ZMQ_FD, fd, &fd_size);                                                                                                                                                             
    if (rc == -1) { zmq_perror("zmq_getsockopt"); }  
    */                                                                                                                                                              
}                                                                                                                                                                                                                  

void zmq_perror(const char *f)                                                                                                                                                                                     
{                                                                                                                                                                                                                  
    fprintf(stderr, "%s: %s\n", f, zmq_strerror(zmq_errno()));                                                                                                                                                     
    abort();                                                                                                                                                                                                       
}

使用第一(手册页)形式总是产生运行以上:

zmq_getsockopt: Invalid argument

但是使用malloc第二,注释掉形式没有问题。 这使得零意义,我因为通过局部变量的地址zmq_getsockopt是完全合法的。

此问题仅在Windows 64位二进制表现; 在Windows或32位二进制的Linux 64位二进制文​​件没有问题。

这似乎也只能用ZMQ_FD套接字选项的问题。 ZMQ_TYPE和ZMQ_SNDHWM工作没有问题。

是否有相关的ZMQ_FD Windows x64上,我是不知道的一些奇怪的行为?

更新

所以,我只注意到我的“工作”的代码实际上是错误的。

sizeof(fd)

是服用的sizeof一个指针在所述第二形式。 事实上,没有任何使用malloc,因为一旦我将其更改为的sizeof(int)的理所应当,我再次得到EINVAL:

/* Fail */
int *fd        = malloc(sizeof(int));                                                                                                                                                                          
size_t fd_size = sizeof(int);                                                                                                                                                                                  
rc = zmq_getsockopt(socket, ZMQ_FD, fd, &fd_size);                                                                                                                                                             
if (rc == -1) { zmq_perror("zmq_getsockopt"); }

事实证明,我显然需要Windows x64上使用64位整型与ZMQ_FD

/* Success! */
uint64_t fd;                                                                                                                                                                                                   
size_t fd_size = sizeof(uint64_t);                                                                                                                                                                             
rc = zmq_getsockopt(socket, ZMQ_FD, &fd, &fd_size);                                                                                                                                                            
if (rc == -1) { zmq_perror("zmq_getsockopt"); }

这是非常令人困惑,因为对于zmq_getsockopt的API为int。 这是一个错误? 一个窗口偏心? 我是密?

相关附录:

ZMQ版本:3.2.3

编译:交叉使用的MinGW-W64,rubenvb-4.8.0编译构建这两个64位和32位二进制文​​件

操作系统:Windows 7

Answer 1:

该zmq_getsockopt手册页说,

在POSIX系统,SOCKET在Windows选项值类型为int



文章来源: zmq_getsockopt returns EINVAL on windows x64 when local address of ZMQ_FD option_val passed