Swift memcpy 与 ZMQ zmq_msg_data 一起使用时没有任何效果 [英] Swift memcpy doesn't have any effect when used with ZMQ zmq_msg_data

查看:164
本文介绍了Swift memcpy 与 ZMQ zmq_msg_data 一起使用时没有任何效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试通过构建一个名为

在我看来,我从 Swift 调用的 memcpy 函数实际上似乎没有做任何事情.这是否是因为我没有将数据有效负载正确传递给 memcpy 函数?我有点卡住了.

解决方案

API-documented zmq_msg_data() 函数很好 &安全阅读"来自已传递的 ZeroMQ 消息的数据部分.

使用环境&参数顺序:

void* memcpy( void* dest,常量无效* src,std::size_t 计数);

表明,您的代码试图存储"尽管 ZeroMQ API 文档中有无数警告不要尝试触摸",但要直接"操作数据的次数更少,因此将数据导入 zmq_msg_t 实例.,但通过使用成员函数:

<块引用>

永远不要直接访问 zmq_msg_t 成员,而是始终使用 zmq_msg 系列职能.

在这里,可能使用 而是 :

int zmq_msg_init_data ( zmq_msg_t *msg,void *data,//<------- 负载加载到 *msgsize_t 大小,zmq_free_fn *ffn,//ref.接口详情void *hint//关于这个);

所以说明性的例子可能是这样的:

<代码>////从提供的缓冲区初始化消息////*************************************************void my_free ( void *data, void *hint )//------- 一个 dealloc helper{免费(数据);}/* ... */void *data = malloc ( 6 );//-------------------- 一个模型有效载荷数据断言(数据);memcpy(数据,ABCDEF",6);zmq_msg_t 味精;rc = zmq_msg_init_data ( &msg, data, 6, my_free, NULL );断言 ( rc == 0&&INF:zmq_msg_init_data() 失败,说"&&zmq_strerror ( zmq_errno() )//------- 非 POSIX 系统解决方法);

另请注意,提议的辩护:

result = zmq_msg_init( &msg );如果 ...

确实在 v2.x 中提供了意义 &v3.x,但在迁移到 v4.x 之后,它开始什么也不做,因为它保留在 ZeroMQ v4.3+ API 中,正如以适当的形式和形状所记录的那样:

<块引用>

返回值

zmq_msg_init() 函数总是返回零.

可能需要一些版本控制和重新设计工作,以便在端口版本和实际 API 版本之间保持一致的处理.

I've been trying to write a libzmq wrapper for Swift by building off of an existing wrapper called SwiftyZeroMQ. However, for our purposes, we require the usage of raw UDP which means we need to use ZeroMQ's Radio/Dish draft method.

I've been able to successfully write a wrapper for receiving data via the Dish socket but I'm now trying to write a wrapper for sending data via the Radio socket. There doesn't seem to be any stuff online regarding how to write a function to send data via the Radio socket but I did come across this. This function in the libzmq repo tests the sending of data via the radio socket so I figured why not try and replicate the function in Swift.

Here's what I've come up with:

Inside the Socket.swift file:

     public func sendRadioMessage(_ group: String, data: NSData) throws{
            var msg = zmq_msg_t.init();
            var result : Int32;
            let flags: SocketSendRecvOption = .none
            
            
            result = zmq_msg_init(&msg);
            if (result == -1) { throw ZeroMQError.last }
        
            defer {
                // Clean up message on scope exit
                zmq_msg_close(&msg)
            }
            
            print("initial msg data = \(zmq_msg_data(&msg))")
            
            print("initial data = \(data)")
            memcpy(zmq_msg_data(&msg), (data as NSData).bytes, data.length);
            
            print("msg size = \(zmq_msg_size(&msg))")
            print("msg = \(zmq_msg_data(&msg))")
            
            result = zmq_msg_set_group(&msg, group);
            if (result == -1) { throw ZeroMQError.last }
            
            result = zmq_msg_send(&msg, self.handle, flags.rawValue);
            if (result == -1) { throw ZeroMQError.last }
            print("sent \(result) bytes")
        }
        
    }

and that function is then called like this:

    public func send(data: String) -> Bool{
        do{
            try radio?.sendRadioMessage(group, data: data.data(using: .utf8) as! NSData);
        }
        catch{
            print("SEND COMMUNICATION error - \(error)");
            return false;
        }
        return true;
    }

   obj.send(data: "Test Data")

This is the console output when running the program:

It seems to me then that the memcpy function that I'm calling from Swift doesn't actually seem to be doing anything. Would this be due to the fact that I'm not passing the data payload properly to the memcpy function? I'm a bit stuck.

解决方案

The API-documented zmq_msg_data() function is fine & safe to "read" a data-part from a delivered ZeroMQ message.

The context of use & the order of parameters :

void* memcpy(        void* dest,
               const void* src,
              std::size_t  count
              );

shows, that your code tries to "store" data into a zmq_msg_t-instance, in spite of countless warnings in the ZeroMQ API documentation not to ever attempt to "touch", the less to manipulate data "directly", but by using member functions :

Never access zmq_msg_t members directly, instead always use the zmq_msg family of functions.

Here, possibly using rather :

int zmq_msg_init_data (   zmq_msg_t *msg, 
                               void *data, // <------- payload to load into *msg
                             size_t  size,
                        zmq_free_fn *ffn,  // ref. API details
                               void *hint  //          on this
                        );

So the illustrative example might be something alike this :

//
// Initialising a message from a supplied buffer
//
// *********************************************

void my_free ( void *data, void *hint ) // ------- a dealloc helper
{
    free ( data );
}

/* ... */

void *data = malloc ( 6 ); // -------------------- a mock-up payload data
assert ( data );
memcpy ( data, "ABCDEF", 6 );

zmq_msg_t msg;
rc = zmq_msg_init_data ( &msg, data, 6, my_free, NULL );
assert (   rc == 0
       && "INF: zmq_msg_init_data() failed, saying"
       &&  zmq_strerror ( zmq_errno() ) // ------- a non-POSIX system workaround
           );

Also note, that a proposed defense of :

result = zmq_msg_init( &msg );
if ...

did gave a sense in v2.x & v3.x, yet after moving into v4.x, it started to do nothing , as it keeps in ZeroMQ v4.3+ API, as is documented in due form and shape :

Return value

The zmq_msg_init() function always returns zero.

Some version-control and redesign efforts might be needed so as to keep handling this consistently between the port-version and the actual API-version.

这篇关于Swift memcpy 与 ZMQ zmq_msg_data 一起使用时没有任何效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆