Swift memcpy 与 ZMQ zmq_msg_data 一起使用时没有任何效果 [英] Swift memcpy doesn't have any effect when used with 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 thezmq_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
Thezmq_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屋!