我正在使用Rust构建一个Redis模块。我找到了一些很好的示例,但是当处理应该接受变长参数的C函数时遇到了困难。
Redis模块C SDK有一个名为
在Rust中,我遵循 Redis-Cell中的模式,它是一个已成功实现的Rust Redis模块。该模块非常棒,但处理这个特殊问题的方式非常有限。实际上,它以一种有点蛮力的方式接受最多三个参数:
这些
我需要能够在运行时传入n个参数,其中n由程序确定,因此硬编码的方法不实用。我知道Rust对可变参数函数的支持有限,并且我已经阅读了RFC 2137的一些内容,但我不确定是否适用于这种情况。
我正在寻找一种将参数向量应用于RedisModule_Call的方法,或者类似于参数展开语法的东西。我相对而言是Rust的新手,但我已经进行了搜索,但似乎找不到在Rust中解决这个问题的任何方法。
澄清一下 - 我可以轻松地将参数传递给RedisModule_Call(它是可变参数的),但是我无法找到一种在Rust中传递可变数量的参数到C函数的语法方式。我的目标是实现类似于以下内容:
Redis模块C SDK有一个名为
RedisModule_Call
的函数,它接受一些特定的参数,然后是代表Redis命令的n
个参数。从Redis模块SDK文档(用C编写)中可以看到:RedisModuleCallReply *reply;
reply = RedisModule_Call(ctx,"INCR","sc",argv[1],"10");
RedisModule_Call
的前三个参数是特定的,但其余参数代表可能有数百个参数的Redis命令。在Rust中,我遵循 Redis-Cell中的模式,它是一个已成功实现的Rust Redis模块。该模块非常棒,但处理这个特殊问题的方式非常有限。实际上,它以一种有点蛮力的方式接受最多三个参数:
pub fn call(&self, command: &str, args: &[&str]) -> Result<Reply, CellError> {
// ... code ...
let raw_reply = match args.len() {
1 => raw::call1::call(/* ... */),
2 => raw::call2::call(/* ... */),
// ...
这些
call1
和call2
函数实际上只是处理不同参数长度的存根。pub mod call2 {
use redis::raw;
pub fn call(
ctx: *mut raw::RedisModuleCtx,
cmdname: *const u8,
fmt: *const u8,
arg0: *mut raw::RedisModuleString,
arg1: *mut raw::RedisModuleString,
) -> *mut raw::RedisModuleCallReply {
unsafe { RedisModule_Call(ctx, cmdname, fmt, arg0, arg1) }
}
#[allow(improper_ctypes)]
extern "C" {
pub static RedisModule_Call: extern "C" fn(
ctx: *mut raw::RedisModuleCtx,
cmdname: *const u8,
fmt: *const u8,
arg0: *mut raw::RedisModuleString,
arg1: *mut raw::RedisModuleString,
) -> *mut raw::RedisModuleCallReply;
}
}
我需要能够在运行时传入n个参数,其中n由程序确定,因此硬编码的方法不实用。我知道Rust对可变参数函数的支持有限,并且我已经阅读了RFC 2137的一些内容,但我不确定是否适用于这种情况。
我正在寻找一种将参数向量应用于RedisModule_Call的方法,或者类似于参数展开语法的东西。我相对而言是Rust的新手,但我已经进行了搜索,但似乎找不到在Rust中解决这个问题的任何方法。
澄清一下 - 我可以轻松地将参数传递给RedisModule_Call(它是可变参数的),但是我无法找到一种在Rust中传递可变数量的参数到C函数的语法方式。我的目标是实现类似于以下内容:
impl Redis {
pub fn call(&self, command: &str, args: &[&str]) -> Result<Reply, CellError> {
/* ... */
unsafe { RedisModule_Call(ctx, cmdname, fmt, ...args) }
/* ... */
...args
是一种黑魔法,可以让 args 表示一个参数或 100 个参数,这相当于 RedisModule_Call(ctx, cmdname, fmt, args[0], args[1] /* ... and so on */)
。